diff --git a/core/core.services.yml b/core/core.services.yml
index 32881da..cf4ebab 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -4,24 +4,6 @@ services:
arguments: ['@settings']
calls:
- [setContainer, ['@service_container']]
- cache_contexts:
- class: Drupal\Core\Cache\CacheContexts
- arguments: ['@service_container', '%cache_contexts%' ]
- cache_context.url:
- class: Drupal\Core\Cache\UrlCacheContext
- arguments: ['@request']
- tags:
- - { name: cache.context}
- cache_context.language:
- class: Drupal\Core\Cache\LanguageCacheContext
- arguments: ['@language_manager']
- tags:
- - { name: cache.context}
- cache_context.theme:
- class: Drupal\Core\Cache\ThemeCacheContext
- arguments: ['@request', '@theme.negotiator']
- tags:
- - { name: cache.context}
cache.backend.database:
class: Drupal\Core\Cache\DatabaseBackendFactory
arguments: ['@database']
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index e38cfda..9e5c50f 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -900,13 +900,6 @@ function drupal_serve_page_from_cache(stdClass $cache, Response $response, Reque
// max-age > 0, allowing the page to be cached by external proxies, when a
// session cookie is present unless the Vary header has been replaced.
$max_age = !$request->cookies->has(session_name()) || isset($boot_headers['vary']) ? $config->get('cache.page.max_age') : 0;
- // RFC 2616, section 14.21 says: 'To mark a response as "never expires," an
- // origin server sends an Expires date approximately one year from the time
- // the response is sent. HTTP/1.1 servers SHOULD NOT send Expires dates more
- // than one year in the future.'
- if ($max_age > 31536000 || $max_age === \Drupal\Core\Cache\Cache::PERMANENT) {
- $max_age = 31536000;
- }
$response->headers->set('Cache-Control', 'public, max-age=' . $max_age);
// Entity tag should change if the output changes.
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 7bb6d06..b7dfde2 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -132,6 +132,78 @@
const JS_THEME = 100;
/**
+ * @defgroup block_caching Block Caching
+ * @{
+ * Constants that define each block's caching state.
+ *
+ * Modules specify how their blocks can be cached in their hook_block_info()
+ * implementations. Caching can be turned off (DRUPAL_NO_CACHE), managed by the
+ * module declaring the block (DRUPAL_CACHE_CUSTOM), or managed by the core
+ * Block module. If the Block module is managing the cache, you can specify that
+ * the block is the same for every page and user (DRUPAL_CACHE_GLOBAL), or that
+ * it can change depending on the page (DRUPAL_CACHE_PER_PAGE) or by user
+ * (DRUPAL_CACHE_PER_ROLE or DRUPAL_CACHE_PER_USER). Page and user settings can
+ * be combined with a bitwise-binary or operator; for example,
+ * DRUPAL_CACHE_PER_ROLE | DRUPAL_CACHE_PER_PAGE means that the block can change
+ * depending on the user role or page it is on.
+ *
+ * The block cache is cleared when the 'content' cache tag is invalidated,
+ * following the same pattern as the page cache (node, comment, user, taxonomy
+ * added or updated...).
+ *
+ * Note that user 1 is excluded from block caching.
+ */
+
+/**
+ * The block should not get cached.
+ *
+ * This setting should be used:
+ * - For simple blocks (notably those that do not perform any db query), where
+ * querying the db cache would be more expensive than directly generating the
+ * content.
+ * - For blocks that change too frequently.
+ */
+const DRUPAL_NO_CACHE = -1;
+
+/**
+ * The block is handling its own caching in its hook_block_view().
+ *
+ * This setting is useful when time based expiration is needed or a site uses a
+ * node access which invalidates standard block cache.
+ */
+const DRUPAL_CACHE_CUSTOM = -2;
+
+/**
+ * The block or element can change depending on the user's roles.
+ *
+ * This is the default setting for blocks, used when the block does not specify
+ * anything.
+ */
+const DRUPAL_CACHE_PER_ROLE = 0x0001;
+
+/**
+ * The block or element can change depending on the user.
+ *
+ * This setting can be resource-consuming for sites with large number of users,
+ * and thus should only be used when DRUPAL_CACHE_PER_ROLE is not sufficient.
+ */
+const DRUPAL_CACHE_PER_USER = 0x0002;
+
+/**
+ * The block or element can change depending on the page being viewed.
+ */
+const DRUPAL_CACHE_PER_PAGE = 0x0004;
+
+/**
+ * The block or element is the same for every user and page that it is visible.
+ */
+const DRUPAL_CACHE_GLOBAL = 0x0008;
+
+/**
+ * @} End of "defgroup block_caching".
+ */
+
+/**
* The delimiter used to split plural strings.
*
* This is the ETX (End of text) character and is used as a minimal means to
@@ -3646,12 +3718,16 @@ function drupal_render_page($page) {
* associative array with one or several of the following keys:
* - 'keys': An array of one or more keys that identify the element. If
* 'keys' is set, the cache ID is created automatically from these keys.
- * Cache keys may either be static (just strings) or tokens (placeholders
- * that are converted to static keys by the @cache_contexts service,
- * depending on the request). See drupal_render_cid_create().
+ * See drupal_render_cid_create().
+ * - 'granularity' (optional): Define the cache granularity using binary
+ * combinations of the cache granularity constants, e.g.
+ * DRUPAL_CACHE_PER_USER to cache for each user separately or
+ * DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE to cache separately for
+ * each page and role. If not specified the element is cached globally for
+ * each theme and language.
* - 'cid': Specify the cache ID directly. Either 'keys' or 'cid' is
- * required. If 'cid' is set, 'keys' is ignored. Use only if you have
- * special requirements.
+ * required. If 'cid' is set, 'keys' and 'granularity' are ignored. Use
+ * only if you have special requirements.
* - 'expire': Set to one of the cache lifetime constants.
* - 'bin': Specify a cache bin to cache the element in. Default is 'cache'.
* - If this element has #type defined and the default attributes for this
@@ -4435,10 +4511,100 @@ function drupal_cache_tags_page_get(Response $response) {
}
/**
+ * Prepares an element for caching based on a query.
+ *
+ * This smart caching strategy saves Drupal from querying and rendering to HTML
+ * when the underlying query is unchanged.
+ *
+ * Expensive queries should use the query builder to create the query and then
+ * call this function. Executing the query and formatting results should happen
+ * in a #pre_render callback.
+ *
+ * @param $query
+ * A select query object as returned by db_select().
+ * @param $function
+ * The name of the function doing this caching. A _pre_render suffix will be
+ * added to this string and is also part of the cache key in
+ * drupal_render_cache_set() and drupal_render_cache_get().
+ * @param $expire
+ * The cache expire time, passed eventually to \Drupal::cache()->set().
+ * @param $granularity
+ * One or more granularity constants passed to drupal_render_cid_parts().
+ *
+ * @return
+ * A renderable array with the following keys and values:
+ * - #query: The passed-in $query.
+ * - #pre_render: $function with a _pre_render suffix.
+ * - #cache: An associative array prepared for drupal_render_cache_set().
+ */
+function drupal_render_cache_by_query($query, $function, $expire = Cache::PERMANENT, $granularity = NULL) {
+ $cache_keys = array_merge(array($function), drupal_render_cid_parts($granularity));
+ $query->preExecute();
+ $cache_keys[] = hash('sha256', serialize(array((string) $query, $query->getArguments())));
+ return array(
+ '#query' => $query,
+ '#pre_render' => array($function . '_pre_render'),
+ '#cache' => array(
+ 'keys' => $cache_keys,
+ 'expire' => $expire,
+ ),
+ );
+}
+
+/**
+ * Returns cache ID parts for building a cache ID.
+ *
+ * @param $granularity
+ * One or more cache granularity constants. For example, to cache separately
+ * for each user, use DRUPAL_CACHE_PER_USER. To cache separately for each
+ * page and role, use the expression:
+ * @code
+ * DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE
+ * @endcode
+ *
+ * @return
+ * An array of cache ID parts, always containing the active theme. If the
+ * locale module is enabled it also contains the active language. If
+ * $granularity was passed in, more parts are added.
+ */
+function drupal_render_cid_parts($granularity = NULL) {
+ global $theme, $base_root;
+
+ $cid_parts[] = $theme;
+
+ // If we have only one language enabled we do not need it as cid part.
+ $language_manager = \Drupal::languageManager();
+ if ($language_manager->isMultilingual()) {
+ foreach ($language_manager->getLanguageTypes() as $type) {
+ $cid_parts[] = $language_manager->getCurrentLanguage($type)->id;
+ }
+ }
+
+ if (!empty($granularity)) {
+ // 'PER_ROLE' and 'PER_USER' are mutually exclusive. 'PER_USER' can be a
+ // resource drag for sites with many users, so when a module is being
+ // equivocal, we favor the less expensive 'PER_ROLE' pattern.
+ if ($granularity & DRUPAL_CACHE_PER_ROLE) {
+ $cid_parts[] = 'r.' . implode(',', \Drupal::currentUser()->getRoles());
+ }
+ elseif ($granularity & DRUPAL_CACHE_PER_USER) {
+ $cid_parts[] = 'u.' . \Drupal::currentUser()->id();
+ }
+
+ if ($granularity & DRUPAL_CACHE_PER_PAGE) {
+ $cid_parts[] = $base_root . request_uri();
+ }
+ }
+
+ return $cid_parts;
+}
+
+/**
* Creates the cache ID for a renderable element.
*
* This creates the cache ID string, either by returning the #cache['cid']
- * property if present or by building the cache ID out of the #cache['keys'].
+ * property if present or by building the cache ID out of the #cache['keys']
+ * and, optionally, the #cache['granularity'] properties.
*
* @param $elements
* A renderable array.
@@ -4451,12 +4617,10 @@ function drupal_render_cid_create($elements) {
return $elements['#cache']['cid'];
}
elseif (isset($elements['#cache']['keys'])) {
- // Cache keys may either be static (just strings) or tokens (placeholders
- // that are converted to static keys by the @cache_contexts service,
- // depending on the request).
- $cache_contexts = \Drupal::service("cache_contexts");
- $keys = $cache_contexts->convertTokensToKeys($elements['#cache']['keys']);
- return implode(':', $keys);
+ $granularity = isset($elements['#cache']['granularity']) ? $elements['#cache']['granularity'] : NULL;
+ // Merge in additional cache ID parts based provided by drupal_render_cid_parts().
+ $cid_parts = array_merge($elements['#cache']['keys'], drupal_render_cid_parts($granularity));
+ return implode(':', $cid_parts);
}
return FALSE;
}
diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 2859b59..51b0f79 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -423,6 +423,25 @@ function entity_access_controller($entity_type) {
}
/**
+ * Returns an entity list controller for a given entity type.
+ *
+ * @param string $entity_type
+ * The type of the entity.
+ *
+ * @return \Drupal\Core\Entity\EntityListControllerInterface
+ * An entity list controller.
+ *
+ * @see \Drupal\Core\Entity\EntityManagerInterface::getListController().
+ *
+ * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
+ * Use \Drupal::entityManager()->getListController().
+ */
+function entity_list_controller($entity_type) {
+ return \Drupal::entityManager()
+ ->getListController($entity_type);
+}
+
+/**
* Returns the render array for an entity.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
diff --git a/core/lib/Drupal/Core/Cache/Cache.php b/core/lib/Drupal/Core/Cache/Cache.php
index ad59409..f224d14 100644
--- a/core/lib/Drupal/Core/Cache/Cache.php
+++ b/core/lib/Drupal/Core/Cache/Cache.php
@@ -7,8 +7,6 @@
namespace Drupal\Core\Cache;
-use Drupal\Core\Database\Query\SelectInterface;
-
/**
* Helper methods for cache.
*
@@ -74,26 +72,4 @@ public static function getBins() {
return $bins;
}
- /**
- * Generates a hash from a query object, to be used as part of the cache key.
- *
- * This smart caching strategy saves Drupal from querying and rendering to
- * HTML when the underlying query is unchanged.
- *
- * Expensive queries should use the query builder to create the query and then
- * call this function. Executing the query and formatting results should
- * happen in a #pre_render callback.
- *
- * @param \Drupal\Core\Database\Query\SelectInterface $query
- * A select query object.
- *
- * @return string
- * A hash of the query arguments.
- */
- public static function keyFromQuery(SelectInterface $query) {
- $query->preExecute();
- $keys = array((string) $query, $query->getArguments());
- return hash('sha256', serialize($keys));
- }
-
}
diff --git a/core/lib/Drupal/Core/Cache/CacheBackendInterface.php b/core/lib/Drupal/Core/Cache/CacheBackendInterface.php
index f0e9882..0208b77 100644
--- a/core/lib/Drupal/Core/Cache/CacheBackendInterface.php
+++ b/core/lib/Drupal/Core/Cache/CacheBackendInterface.php
@@ -21,7 +21,7 @@
/**
* Indicates that the item should never be removed unless explicitly deleted.
*/
- const CACHE_PERMANENT = -1;
+ const CACHE_PERMANENT = 0;
/**
* Returns data from the persistent cache.
diff --git a/core/lib/Drupal/Core/Cache/CacheContextInterface.php b/core/lib/Drupal/Core/Cache/CacheContextInterface.php
deleted file mode 100644
index fd9783a..0000000
--- a/core/lib/Drupal/Core/Cache/CacheContextInterface.php
+++ /dev/null
@@ -1,34 +0,0 @@
-container = $container;
- $this->contexts = $contexts;
- }
-
- /**
- * Provides an array of available cache contexts.
- *
- * @return array
- * An array of available cache contexts.
- */
- public function getAll() {
- return $this->contexts;
- }
-
- /**
- * Provides an array of available cache context labels.
- *
- * To be used in cache configuration forms.
- *
- * @return array
- * An array of available cache contexts and corresponding labels.
- */
- public function getLabels() {
- $with_labels = array();
- foreach ($this->contexts as $context) {
- $with_labels[$context] = $this->getService($context)->getLabel();
- }
- return $with_labels;
- }
-
- /**
- * Converts cache context tokens to string representations of the context.
- *
- * Cache keys may either be static (just strings) or tokens (placeholders
- * that are converted to static keys by the @cache_contexts service, depending
- * depending on the request). This is the default cache contexts service.
- *
- * @param array $keys
- * An array of cache keys that may or may not contain cache context tokens.
- *
- * @return array
- * A copy of the input, with cache context tokens converted.
- */
- public function convertTokensToKeys(array $keys) {
- $context_keys = array_intersect($keys, $this->getAll());
- $new_keys = $keys;
-
- // Iterate over the indices instead of the values so that the order of the
- // cache keys are preserved.
- foreach (array_keys($context_keys) as $index) {
- $new_keys[$index] = $this->getContext($keys[$index]);
- }
- return $new_keys;
- }
-
- /**
- * Provides the string representaton of a cache context.
- *
- * @param string $context
- * A cache context token of an available cache context service.
- *
- * @return string
- * The string representaton of a cache context.
- */
- protected function getContext($context) {
- return $this->getService($context)->getContext();
- }
-
- /**
- * Retrieves a service from the container.
- *
- * @param string $service
- * The ID of the service to retrieve.
- *
- * @return mixed
- * The specified service.
- */
- protected function getService($service) {
- return $this->container->get($service);
- }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/CacheContextsPass.php b/core/lib/Drupal/Core/Cache/CacheContextsPass.php
deleted file mode 100644
index 645df03..0000000
--- a/core/lib/Drupal/Core/Cache/CacheContextsPass.php
+++ /dev/null
@@ -1,28 +0,0 @@
-findTaggedServiceIds('cache.context'));
- $container->setParameter('cache_contexts', $cache_contexts);
- }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/LanguageCacheContext.php b/core/lib/Drupal/Core/Cache/LanguageCacheContext.php
deleted file mode 100644
index b73652f..0000000
--- a/core/lib/Drupal/Core/Cache/LanguageCacheContext.php
+++ /dev/null
@@ -1,54 +0,0 @@
-languageManager = $language_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function getLabel() {
- return t('Language');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getContext() {
- $context_parts = array();
- if ($this->language_manager->isMultilingual()) {
- foreach ($this->language_manager->getLanguageTypes() as $type) {
- $context_parts[] = $this->language_manager->getCurrentLanguage($type)->id;
- }
- }
- return implode(':', $context_parts);
- }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/ThemeCacheContext.php b/core/lib/Drupal/Core/Cache/ThemeCacheContext.php
deleted file mode 100644
index d777471..0000000
--- a/core/lib/Drupal/Core/Cache/ThemeCacheContext.php
+++ /dev/null
@@ -1,59 +0,0 @@
-request = $request;
- $this->themeNegotiator = $theme_negotiator;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function getLabel() {
- return t('Theme');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getContext() {
- return $this->themeNegotiator->determineActiveTheme($this->request) ?: 'stark';
- }
-
-}
diff --git a/core/lib/Drupal/Core/Cache/UrlCacheContext.php b/core/lib/Drupal/Core/Cache/UrlCacheContext.php
deleted file mode 100644
index 596e134..0000000
--- a/core/lib/Drupal/Core/Cache/UrlCacheContext.php
+++ /dev/null
@@ -1,48 +0,0 @@
-request = $request;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function getLabel() {
- return t('URL');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getContext() {
- return $this->request->getUri();
- }
-
-}
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php
deleted file mode 100644
index 601de73..0000000
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php
+++ /dev/null
@@ -1,54 +0,0 @@
-entityType->getClass(), 'sort'));
- return $entities;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
-
- if ($this->entityType->hasKey('status')) {
- if (!$entity->status() && $entity->hasLinkTemplate('enable')) {
- $operations['enable'] = array(
- 'title' => t('Enable'),
- 'weight' => -10,
- ) + $entity->urlInfo('enable');
- }
- elseif ($entity->hasLinkTemplate('disable')) {
- $operations['disable'] = array(
- 'title' => t('Disable'),
- 'weight' => 40,
- ) + $entity->urlInfo('disable');
- }
- }
-
- return $operations;
- }
-
-}
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php
new file mode 100644
index 0000000..54afad2
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php
@@ -0,0 +1,54 @@
+entityType->getClass(), 'sort'));
+ return $entities;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+
+ if ($this->entityType->hasKey('status')) {
+ if (!$entity->status() && $entity->hasLinkTemplate('enable')) {
+ $operations['enable'] = array(
+ 'title' => t('Enable'),
+ 'weight' => -10,
+ ) + $entity->urlInfo('enable');
+ }
+ elseif ($entity->hasLinkTemplate('disable')) {
+ $operations['disable'] = array(
+ 'title' => t('Disable'),
+ 'weight' => 40,
+ ) + $entity->urlInfo('disable');
+ }
+ }
+
+ return $operations;
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Config/Entity/DraggableListBuilder.php b/core/lib/Drupal/Core/Config/Entity/DraggableListBuilder.php
deleted file mode 100644
index cb68a0e..0000000
--- a/core/lib/Drupal/Core/Config/Entity/DraggableListBuilder.php
+++ /dev/null
@@ -1,171 +0,0 @@
-entityType->hasKey('weight')) {
- $this->weightKey = $this->entityType->getKey('weight');
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header = array();
- if (!empty($this->weightKey)) {
- $header['weight'] = t('Weight');
- }
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row = array();
- if (!empty($this->weightKey)) {
- // Override default values to markup elements.
- $row['#attributes']['class'][] = 'draggable';
- $row['#weight'] = $entity->get($this->weightKey);
- // Add weight column.
- $row['weight'] = array(
- '#type' => 'weight',
- '#title' => t('Weight for @title', array('@title' => $entity->label())),
- '#title_display' => 'invisible',
- '#default_value' => $entity->get($this->weightKey),
- '#attributes' => array('class' => array('weight')),
- );
- }
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function render() {
- if (!empty($this->weightKey)) {
- return $this->formBuilder()->getForm($this);
- }
- return parent::render();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildForm(array $form, array &$form_state) {
- $form[$this->entitiesKey] = array(
- '#type' => 'table',
- '#header' => $this->buildHeader(),
- '#empty' => t('There is no @label yet.', array('@label' => $this->entityType->getLabel())),
- '#tabledrag' => array(
- array(
- 'action' => 'order',
- 'relationship' => 'sibling',
- 'group' => 'weight',
- ),
- ),
- );
-
- $this->entities = $this->load();
- foreach ($this->entities as $entity) {
- $row = $this->buildRow($entity);
- if (isset($row['label'])) {
- $row['label'] = array('#markup' => $row['label']);
- }
- $form[$this->entitiesKey][$entity->id()] = $row;
- }
-
- $form['actions']['#type'] = 'actions';
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save order'),
- '#button_type' => 'primary',
- );
-
- return $form;
- }
-
- /**
- * {@inheritdoc}
- */
- public function validateForm(array &$form, array &$form_state) {
- // No validation.
- }
-
- /**
- * {@inheritdoc}
- */
- public function submitForm(array &$form, array &$form_state) {
- foreach ($form_state['values'][$this->entitiesKey] as $id => $value) {
- if (isset($this->entities[$id]) && $this->entities[$id]->get($this->weightKey) != $value['weight']) {
- // Save entity only when its weight was changed.
- $this->entities[$id]->set($this->weightKey, $value['weight']);
- $this->entities[$id]->save();
- }
- }
- }
-
- /**
- * Returns the form builder.
- *
- * @return \Drupal\Core\Form\FormBuilderInterface
- * The form builder.
- */
- protected function formBuilder() {
- if (!$this->formBuilder) {
- $this->formBuilder = \Drupal::formBuilder();
- }
- return $this->formBuilder;
- }
-
-}
diff --git a/core/lib/Drupal/Core/Config/Entity/DraggableListController.php b/core/lib/Drupal/Core/Config/Entity/DraggableListController.php
new file mode 100644
index 0000000..f2c3ff8
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/Entity/DraggableListController.php
@@ -0,0 +1,171 @@
+entityType->hasKey('weight')) {
+ $this->weightKey = $this->entityType->getKey('weight');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header = array();
+ if (!empty($this->weightKey)) {
+ $header['weight'] = t('Weight');
+ }
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row = array();
+ if (!empty($this->weightKey)) {
+ // Override default values to markup elements.
+ $row['#attributes']['class'][] = 'draggable';
+ $row['#weight'] = $entity->get($this->weightKey);
+ // Add weight column.
+ $row['weight'] = array(
+ '#type' => 'weight',
+ '#title' => t('Weight for @title', array('@title' => $entity->label())),
+ '#title_display' => 'invisible',
+ '#default_value' => $entity->get($this->weightKey),
+ '#attributes' => array('class' => array('weight')),
+ );
+ }
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ if (!empty($this->weightKey)) {
+ return $this->formBuilder()->getForm($this);
+ }
+ return parent::render();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state) {
+ $form[$this->entitiesKey] = array(
+ '#type' => 'table',
+ '#header' => $this->buildHeader(),
+ '#empty' => t('There is no @label yet.', array('@label' => $this->entityType->getLabel())),
+ '#tabledrag' => array(
+ array(
+ 'action' => 'order',
+ 'relationship' => 'sibling',
+ 'group' => 'weight',
+ ),
+ ),
+ );
+
+ $this->entities = $this->load();
+ foreach ($this->entities as $entity) {
+ $row = $this->buildRow($entity);
+ if (isset($row['label'])) {
+ $row['label'] = array('#markup' => $row['label']);
+ }
+ $form[$this->entitiesKey][$entity->id()] = $row;
+ }
+
+ $form['actions']['#type'] = 'actions';
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save order'),
+ '#button_type' => 'primary',
+ );
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, array &$form_state) {
+ // No validation.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ foreach ($form_state['values'][$this->entitiesKey] as $id => $value) {
+ if (isset($this->entities[$id]) && $this->entities[$id]->get($this->weightKey) != $value['weight']) {
+ // Save entity only when its weight was changed.
+ $this->entities[$id]->set($this->weightKey, $value['weight']);
+ $this->entities[$id]->save();
+ }
+ }
+ }
+
+ /**
+ * Returns the form builder.
+ *
+ * @return \Drupal\Core\Form\FormBuilderInterface
+ * The form builder.
+ */
+ protected function formBuilder() {
+ if (!$this->formBuilder) {
+ $this->formBuilder = \Drupal::formBuilder();
+ }
+ return $this->formBuilder;
+ }
+
+}
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 01ab877..d835f6e 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -7,7 +7,6 @@
namespace Drupal\Core;
-use Drupal\Core\Cache\CacheContextsPass;
use Drupal\Core\Cache\ListCacheBinsPass;
use Drupal\Core\Config\ConfigFactoryOverridePass;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
@@ -73,7 +72,6 @@ public function register(ContainerBuilder $container) {
$container->addCompilerPass(new RegisterPathProcessorsPass());
$container->addCompilerPass(new RegisterRouteProcessorsPass());
$container->addCompilerPass(new ListCacheBinsPass());
- $container->addCompilerPass(new CacheContextsPass());
// Add the compiler pass for appending string translators.
$container->addCompilerPass(new RegisterStringTranslatorsPass());
// Add the compiler pass that will process the tagged breadcrumb builder
diff --git a/core/lib/Drupal/Core/Entity/Controller/EntityListController.php b/core/lib/Drupal/Core/Entity/Controller/EntityListController.php
index 1b081bb..7a07a38 100644
--- a/core/lib/Drupal/Core/Entity/Controller/EntityListController.php
+++ b/core/lib/Drupal/Core/Entity/Controller/EntityListController.php
@@ -25,7 +25,7 @@ class EntityListController extends ControllerBase {
* A render array as expected by drupal_render().
*/
public function listing($entity_type) {
- return $this->entityManager()->getListBuilder($entity_type)->render();
+ return $this->entityManager()->getListController($entity_type)->render();
}
}
diff --git a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
index aac92bc..31672c0 100644
--- a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
+++ b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
@@ -25,7 +25,7 @@ class EntityViewController implements ContainerInjectionInterface {
protected $entityManager;
/**
- * Creates an EntityViewController object.
+ * Creates an EntityListController object.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
diff --git a/core/lib/Drupal/Core/Entity/EntityListBuilder.php b/core/lib/Drupal/Core/Entity/EntityListBuilder.php
deleted file mode 100644
index 626c275..0000000
--- a/core/lib/Drupal/Core/Entity/EntityListBuilder.php
+++ /dev/null
@@ -1,207 +0,0 @@
-get('entity.manager')->getStorageController($entity_type->id())
- );
- }
-
- /**
- * Constructs a new EntityListBuilder object.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type definition.
- * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage
- * The entity storage controller class.
- */
- public function __construct(EntityTypeInterface $entity_type, EntityStorageControllerInterface $storage) {
- $this->entityTypeId = $entity_type->id();
- $this->storage = $storage;
- $this->entityType = $entity_type;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getStorageController() {
- return $this->storage;
- }
-
- /**
- * {@inheritdoc}
- */
- public function load() {
- return $this->storage->loadMultiple();
- }
-
- /**
- * Returns the escaped label of an entity.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity being listed.
- *
- * @return string
- * The escaped entity label.
- */
- protected function getLabel(EntityInterface $entity) {
- return String::checkPlain($entity->label());
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = array();
- if ($entity->access('update') && $entity->hasLinkTemplate('edit-form')) {
- $operations['edit'] = array(
- 'title' => $this->t('Edit'),
- 'weight' => 10,
- ) + $entity->urlInfo('edit-form');
- }
- if ($entity->access('delete') && $entity->hasLinkTemplate('delete-form')) {
- $operations['delete'] = array(
- 'title' => $this->t('Delete'),
- 'weight' => 100,
- ) + $entity->urlInfo('delete-form');
- }
-
- return $operations;
- }
-
- /**
- * Builds the header row for the entity listing.
- *
- * @return array
- * A render array structure of header strings.
- *
- * @see \Drupal\Core\Entity\EntityListBuilder::render()
- */
- public function buildHeader() {
- $row['operations'] = $this->t('Operations');
- return $row;
- }
-
- /**
- * Builds a row for an entity in the entity listing.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity for this row of the list.
- *
- * @return array
- * A render array structure of fields for this entity.
- *
- * @see \Drupal\Core\Entity\EntityListBuilder::render()
- */
- public function buildRow(EntityInterface $entity) {
- $row['operations']['data'] = $this->buildOperations($entity);
- return $row;
- }
-
- /**
- * Builds a renderable list of operation links for the entity.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity on which the linked operations will be performed.
- *
- * @return array
- * A renderable array of operation links.
- *
- * @see \Drupal\Core\Entity\EntityListBuilder::buildRow()
- */
- public function buildOperations(EntityInterface $entity) {
- // Retrieve and sort operations.
- $operations = $this->getOperations($entity);
- $this->moduleHandler()->alter('entity_operation', $operations, $entity);
- uasort($operations, array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
- $build = array(
- '#type' => 'operations',
- '#links' => $operations,
- );
- return $build;
- }
-
- /**
- * {@inheritdoc}
- *
- * Builds the entity listing as renderable array for theme_table().
- *
- * @todo Add a link to add a new item to the #empty text.
- */
- public function render() {
- $build = array(
- '#type' => 'table',
- '#header' => $this->buildHeader(),
- '#title' => $this->getTitle(),
- '#rows' => array(),
- '#empty' => $this->t('There is no @label yet.', array('@label' => $this->entityType->getLabel())),
- );
- foreach ($this->load() as $entity) {
- if ($row = $this->buildRow($entity)) {
- $build['#rows'][$entity->id()] = $row;
- }
- }
- return $build;
- }
-
- /**
- * Translates a string to the current language or to a given language.
- *
- * See the t() documentation for details.
- */
- protected function t($string, array $args = array(), array $options = array()) {
- return $this->translationManager()->translate($string, $args, $options);
- }
-
- /**
- * Returns the title of the page.
- *
- * @return string
- * A string title of the page.
- */
- protected function getTitle() {
- return;
- }
-
-}
diff --git a/core/lib/Drupal/Core/Entity/EntityListBuilderInterface.php b/core/lib/Drupal/Core/Entity/EntityListBuilderInterface.php
deleted file mode 100644
index 99f5935..0000000
--- a/core/lib/Drupal/Core/Entity/EntityListBuilderInterface.php
+++ /dev/null
@@ -1,58 +0,0 @@
-get('entity.manager')->getStorageController($entity_type->id())
+ );
+ }
+
+ /**
+ * Constructs a new EntityListController object.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type definition.
+ * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage
+ * The entity storage controller class.
+ */
+ public function __construct(EntityTypeInterface $entity_type, EntityStorageControllerInterface $storage) {
+ $this->entityTypeId = $entity_type->id();
+ $this->storage = $storage;
+ $this->entityType = $entity_type;
+ }
+
+ /**
+ * Implements \Drupal\Core\Entity\EntityListControllerInterface::getStorageController().
+ */
+ public function getStorageController() {
+ return $this->storage;
+ }
+
+ /**
+ * Implements \Drupal\Core\Entity\EntityListControllerInterface::load().
+ */
+ public function load() {
+ return $this->storage->loadMultiple();
+ }
+
+ /**
+ * Returns the escaped label of an entity.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ * The entity being listed.
+ *
+ * @return string
+ * The escaped entity label.
+ */
+ protected function getLabel(EntityInterface $entity) {
+ return String::checkPlain($entity->label());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = array();
+ if ($entity->access('update') && $entity->hasLinkTemplate('edit-form')) {
+ $operations['edit'] = array(
+ 'title' => $this->t('Edit'),
+ 'weight' => 10,
+ ) + $entity->urlInfo('edit-form');
+ }
+ if ($entity->access('delete') && $entity->hasLinkTemplate('delete-form')) {
+ $operations['delete'] = array(
+ 'title' => $this->t('Delete'),
+ 'weight' => 100,
+ ) + $entity->urlInfo('delete-form');
+ }
+
+ return $operations;
+ }
+
+ /**
+ * Builds the header row for the entity listing.
+ *
+ * @return array
+ * A render array structure of header strings.
+ *
+ * @see \Drupal\Core\Entity\EntityListController::render()
+ */
+ public function buildHeader() {
+ $row['operations'] = $this->t('Operations');
+ return $row;
+ }
+
+ /**
+ * Builds a row for an entity in the entity listing.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ * The entity for this row of the list.
+ *
+ * @return array
+ * A render array structure of fields for this entity.
+ *
+ * @see \Drupal\Core\Entity\EntityListController::render()
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['operations']['data'] = $this->buildOperations($entity);
+ return $row;
+ }
+
+ /**
+ * Builds a renderable list of operation links for the entity.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ * The entity on which the linked operations will be performed.
+ *
+ * @return array
+ * A renderable array of operation links.
+ *
+ * @see \Drupal\Core\Entity\EntityListController::render()
+ */
+ public function buildOperations(EntityInterface $entity) {
+ // Retrieve and sort operations.
+ $operations = $this->getOperations($entity);
+ $this->moduleHandler()->alter('entity_operation', $operations, $entity);
+ uasort($operations, array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
+ $build = array(
+ '#type' => 'operations',
+ '#links' => $operations,
+ );
+ return $build;
+ }
+
+ /**
+ * Implements \Drupal\Core\Entity\EntityListControllerInterface::render().
+ *
+ * Builds the entity list as renderable array for theme_table().
+ *
+ * @todo Add a link to add a new item to the #empty text.
+ */
+ public function render() {
+ $build = array(
+ '#type' => 'table',
+ '#header' => $this->buildHeader(),
+ '#title' => $this->getTitle(),
+ '#rows' => array(),
+ '#empty' => $this->t('There is no @label yet.', array('@label' => $this->entityType->getLabel())),
+ );
+ foreach ($this->load() as $entity) {
+ if ($row = $this->buildRow($entity)) {
+ $build['#rows'][$entity->id()] = $row;
+ }
+ }
+ return $build;
+ }
+
+ /**
+ * Translates a string to the current language or to a given language.
+ *
+ * See the t() documentation for details.
+ */
+ protected function t($string, array $args = array(), array $options = array()) {
+ return $this->translationManager()->translate($string, $args, $options);
+ }
+
+ /**
+ * Returns the title of the page.
+ *
+ * @return string
+ * A string title of the page.
+ *
+ */
+ protected function getTitle() {
+ return;
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Entity/EntityListControllerInterface.php b/core/lib/Drupal/Core/Entity/EntityListControllerInterface.php
new file mode 100644
index 0000000..775445e
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/EntityListControllerInterface.php
@@ -0,0 +1,58 @@
+getController($entity_type, 'list_builder', 'getListBuilderClass');
+ public function getListController($entity_type) {
+ return $this->getController($entity_type, 'list', 'getListClass');
}
/**
diff --git a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
index 9a65866..e40ff94 100644
--- a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
@@ -119,15 +119,15 @@ public function clearCachedDefinitions();
public function getViewBuilder($entity_type);
/**
- * Creates a new entity list builder.
+ * Creates a new list controller instance.
*
* @param string $entity_type
- * The entity type for this list builder.
+ * The entity type for this list controller.
*
- * @return \Drupal\Core\Entity\EntityListBuilderInterface
- * An entity list builder instance.
+ * @return \Drupal\Core\Entity\EntityListControllerInterface
+ * A list controller instance.
*/
- public function getListBuilder($entity_type);
+ public function getListController($entity_type);
/**
* Creates a new form controller instance.
diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php
index 93f6062..4eae0df 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -365,23 +365,23 @@ public function hasFormClasses() {
/**
* {@inheritdoc}
*/
- public function getListBuilderClass() {
- return $this->getControllerClass('list_builder');
+ public function getListClass() {
+ return $this->getControllerClass('list');
}
/**
* {@inheritdoc}
*/
- public function setListBuilderClass($class) {
- $this->controllers['list_builder'] = $class;
+ public function setListClass($class) {
+ $this->controllers['list'] = $class;
return $this;
}
/**
* {@inheritdoc}
*/
- public function hasListBuilderClass() {
- return $this->hasControllerClass('list_builder');
+ public function hasListClass() {
+ return $this->hasControllerClass('list');
}
/**
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index 5934322..226dc91 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -194,7 +194,7 @@ public function getControllerClass($controller_type);
* entity forms when the forms are similar. The classes must implement
* \Drupal\Core\Entity\EntityFormControllerInterface.
* - list: The name of the class that provides listings of the entities. The
- * class must implement \Drupal\Core\Entity\EntityListBuilderInterface.
+ * class must implement \Drupal\Core\Entity\EntityListControllerInterface.
* - render: The name of the class that is used to render the entities. The
* class must implement \Drupal\Core\Entity\EntityViewBuilderInterface.
* - access: The name of the class that is used for access checks. The class
@@ -263,7 +263,7 @@ public function hasFormClasses();
* @return string
* The class for this entity type's list.
*/
- public function getListBuilderClass();
+ public function getListClass();
/**
* Sets the list class.
@@ -273,7 +273,7 @@ public function getListBuilderClass();
*
* @return static
*/
- public function setListBuilderClass($class);
+ public function setListClass($class);
/**
* Indicates if this entity type has a list class.
@@ -281,7 +281,7 @@ public function setListBuilderClass($class);
* @return bool
* TRUE if there is a list for this entity type, FALSE otherwise.
*/
- public function hasListBuilderClass();
+ public function hasListClass();
/**
* Returns the view builder class.
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index 2e48ecc..7cbadb2 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -158,14 +158,8 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langco
// type configuration.
if ($this->isViewModeCacheable($view_mode) && !$entity->isNew() && $entity->isDefaultRevision() && $this->entityType->isRenderCacheable()) {
$return['#cache'] += array(
- 'keys' => array(
- 'entity_view',
- $this->entityTypeId,
- $entity->id(),
- $view_mode,
- 'cache_context.theme',
- 'cache_context.user.roles',
- ),
+ 'keys' => array('entity_view', $this->entityTypeId, $entity->id(), $view_mode),
+ 'granularity' => DRUPAL_CACHE_PER_ROLE,
'bin' => $this->cacheBin,
);
diff --git a/core/modules/action/action.module b/core/modules/action/action.module
index e765a24..ee2f628 100644
--- a/core/modules/action/action.module
+++ b/core/modules/action/action.module
@@ -67,7 +67,7 @@ function action_entity_type_build(array &$entity_types) {
->setFormClass('add', 'Drupal\action\ActionAddFormController')
->setFormClass('edit', 'Drupal\action\ActionEditFormController')
->setFormClass('delete', 'Drupal\action\Form\ActionDeleteForm')
- ->setListBuilderClass('Drupal\action\ActionListBuilder')
+ ->setListClass('Drupal\action\ActionListController')
->setLinkTemplate('delete-form', 'action.delete')
->setLinkTemplate('edit-form', 'action.admin_configure');
}
diff --git a/core/modules/action/lib/Drupal/action/ActionListBuilder.php b/core/modules/action/lib/Drupal/action/ActionListBuilder.php
deleted file mode 100644
index 7ef6e19..0000000
--- a/core/modules/action/lib/Drupal/action/ActionListBuilder.php
+++ /dev/null
@@ -1,125 +0,0 @@
-actionManager = $action_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('plugin.manager.action')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function load() {
- $entities = parent::load();
- foreach ($entities as $entity) {
- if ($entity->isConfigurable()) {
- $this->hasConfigurableActions = TRUE;
- continue;
- }
- }
- return $entities;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['type'] = $entity->getType();
- $row['label'] = $this->getLabel($entity);
- if ($this->hasConfigurableActions) {
- $row += parent::buildRow($entity);
- }
- return $row;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header = array(
- 'type' => t('Action type'),
- 'label' => t('Label'),
- ) + parent::buildHeader();
- return $header;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = $entity->isConfigurable() ? parent::getOperations($entity) : array();
- if (isset($operations['edit'])) {
- $operations['edit']['title'] = t('Configure');
- }
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function render() {
- $build['action_header']['#markup'] = '
' . t('Available actions:') . '
';
- $build['action_table'] = parent::render();
- if (!$this->hasConfigurableActions) {
- unset($build['action_table']['#header']['operations']);
- }
- $build['action_admin_manage_form'] = drupal_get_form('Drupal\action\Form\ActionAdminManageForm');
- return $build;
- }
-
-}
diff --git a/core/modules/action/lib/Drupal/action/ActionListController.php b/core/modules/action/lib/Drupal/action/ActionListController.php
new file mode 100644
index 0000000..946bcca
--- /dev/null
+++ b/core/modules/action/lib/Drupal/action/ActionListController.php
@@ -0,0 +1,123 @@
+actionManager = $action_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('plugin.manager.action')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load() {
+ $entities = parent::load();
+ foreach ($entities as $entity) {
+ if ($entity->isConfigurable()) {
+ $this->hasConfigurableActions = TRUE;
+ continue;
+ }
+ }
+ return $entities;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['type'] = $entity->getType();
+ $row['label'] = $this->getLabel($entity);
+ if ($this->hasConfigurableActions) {
+ $row += parent::buildRow($entity);
+ }
+ return $row;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header = array(
+ 'type' => t('Action type'),
+ 'label' => t('Label'),
+ ) + parent::buildHeader();
+ return $header;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = $entity->isConfigurable() ? parent::getOperations($entity) : array();
+ if (isset($operations['edit'])) {
+ $operations['edit']['title'] = t('Configure');
+ }
+ return $operations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ $build['action_header']['#markup'] = '' . t('Available actions:') . '
';
+ $build['action_table'] = parent::render();
+ if (!$this->hasConfigurableActions) {
+ unset($build['action_table']['#header']['operations']);
+ }
+ $build['action_admin_manage_form'] = drupal_get_form('Drupal\action\Form\ActionAdminManageForm');
+ return $build;
+ }
+
+}
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 0aab348..37998b1 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -169,16 +169,52 @@ function block_page_build(&$page) {
function block_get_blocks_by_region($region) {
$build = array();
if ($list = block_list($region)) {
- foreach ($list as $key => $block) {
+ $build = _block_get_renderable_region($list);
+ }
+ return $build;
+}
+
+/**
+ * Gets an array of blocks suitable for drupal_render().
+ *
+ * @param $list
+ * A list of blocks such as that returned by block_list().
+ *
+ * @return
+ * A renderable array.
+ */
+function _block_get_renderable_region($list = array()) {
+ $build = array();
+ // Block caching is not compatible with node_access modules. We also
+ // preserve the submission of forms in blocks, by fetching from cache
+ // only if the request method is 'GET' (or 'HEAD'). User 1 being out of
+ // the regular 'roles define permissions' schema, it brings too many
+ // chances of having unwanted output get in the cache and later be served
+ // to other users. We therefore exclude user 1 from block caching.
+ $not_cacheable = \Drupal::currentUser()->id() == 1 ||
+ count(\Drupal::moduleHandler()->getImplementations('node_grants')) ||
+ !\Drupal::request()->isMethodSafe();
+
+ foreach ($list as $key => $block) {
+ $settings = $block->get('settings');
+ if ($not_cacheable || in_array($settings['cache'], array(DRUPAL_NO_CACHE, DRUPAL_CACHE_CUSTOM))) {
+ // Non-cached blocks get built immediately.
if ($block->access()) {
$build[$key] = entity_view($block, 'block');
}
}
- // If none of the blocks in this region are visible, then don't set anything
- // else in the render array, because that would cause the region to show up.
- if (!empty($build)) {
- // block_list() already returned the blocks in sorted order.
- $build['#sorted'] = TRUE;
+ else {
+ $build[$key] = array(
+ '#block' => $block,
+ '#weight' => $block->get('weight'),
+ '#pre_render' => array('_block_get_renderable_block'),
+ '#cache' => array(
+ 'keys' => array($key, $settings['module']),
+ 'granularity' => $settings['cache'],
+ 'bin' => 'block',
+ 'tags' => array('content' => TRUE),
+ ),
+ );
}
}
return $build;
@@ -306,7 +342,9 @@ function block_list($region) {
$blocks[$region] = array();
}
- uasort($blocks[$region], 'Drupal\block\Entity\Block::sort');
+ uasort($blocks[$region], function($first, $second) {
+ return $first->weight === $second->weight ? 0 : ($first->weight < $second->weight ? -1 : 1);
+ });
return $blocks[$region];
}
@@ -327,6 +365,26 @@ function block_load($entity_id) {
}
/**
+ * Builds the content and label for a block.
+ *
+ * For cacheable blocks, this is called during #pre_render.
+ *
+ * @param $element
+ * A renderable array.
+ *
+ * @return
+ * A renderable array.
+ */
+function _block_get_renderable_block($element) {
+ $block = $element['#block'];
+ // Don't bother to build blocks that aren't accessible.
+ if ($element['#access'] = $block->access()) {
+ $element += entity_view($block, 'block');
+ }
+ return $element;
+}
+
+/**
* Implements hook_rebuild().
*/
function block_rebuild() {
@@ -398,11 +456,6 @@ function template_preprocess_block(&$variables) {
$variables['derivative_plugin_id'] = $variables['elements']['#derivative_plugin_id'];
$variables['label'] = !empty($variables['configuration']['label_display']) ? $variables['configuration']['label'] : '';
$variables['content'] = $variables['elements']['content'];
- // A block's label is configuration: it is static. Allow dynamic labels to be
- // set in the render array.
- if (isset($variables['elements']['content']['#title']) && !empty($variables['configuration']['label_display'])) {
- $variables['label'] = $variables['elements']['content']['#title'];
- }
$variables['attributes']['class'][] = 'block';
$variables['attributes']['class'][] = drupal_html_class('block-' . $variables['configuration']['module']);
diff --git a/core/modules/block/config/schema/block.schema.yml b/core/modules/block/config/schema/block.schema.yml
index a8b1a01..01784bd 100644
--- a/core/modules/block/config/schema/block.schema.yml
+++ b/core/modules/block/config/schema/block.schema.yml
@@ -73,18 +73,8 @@ block.block.*:
type: string
label: 'Display title'
cache:
- type: mapping
- label: 'Cache settings'
- mapping:
- max_age:
- type: integer
- label: 'Maximum age'
- contexts:
- type: sequence
- label: 'Vary by context'
- sequence:
- - type: string
- label: 'Context'
+ type: integer
+ label: 'Cache'
status:
type: boolean
label: 'Status'
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListBuilder.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListBuilder.php
deleted file mode 100644
index 94c9e31..0000000
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListBuilder.php
+++ /dev/null
@@ -1,47 +0,0 @@
-getLabel($entity);
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
- if (isset($operations['edit'])) {
- $operations['edit']['query']['destination'] = 'admin/structure/block/custom-blocks';
- }
- return $operations;
- }
-
-}
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListController.php
new file mode 100644
index 0000000..1f49a87
--- /dev/null
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListController.php
@@ -0,0 +1,45 @@
+getLabel($entity);
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+ if (isset($operations['edit'])) {
+ $operations['edit']['query']['destination'] = 'admin/structure/block/custom-blocks';
+ }
+ return $operations;
+ }
+
+}
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListBuilder.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListBuilder.php
deleted file mode 100644
index 901ef6f..0000000
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListBuilder.php
+++ /dev/null
@@ -1,59 +0,0 @@
-urlInfo();
- $row['type'] = \Drupal::l($entity->label(), $uri['route_name'], $uri['route_parameters'], $uri['options']);
- $row['description'] = filter_xss_admin($entity->description);
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getTitle() {
- return $this->t('Custom block types');
- }
-
-}
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php
new file mode 100644
index 0000000..84a8ad9
--- /dev/null
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php
@@ -0,0 +1,57 @@
+urlInfo();
+ $row['type'] = \Drupal::l($entity->label(), $uri['route_name'], $uri['route_parameters'], $uri['options']);
+ $row['description'] = filter_xss_admin($entity->description);
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getTitle() {
+ return $this->t('Custom block types');
+ }
+
+}
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php
index ea20a79..88d232b 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php
@@ -22,7 +22,7 @@
* bundle_label = @Translation("Custom Block type"),
* controllers = {
* "access" = "Drupal\custom_block\CustomBlockAccessController",
- * "list_builder" = "Drupal\custom_block\CustomBlockListBuilder",
+ * "list" = "Drupal\custom_block\CustomBlockListController",
* "view_builder" = "Drupal\custom_block\CustomBlockViewBuilder",
* "form" = {
* "add" = "Drupal\custom_block\CustomBlockFormController",
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php
index 57ed007..59a4735 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php
@@ -24,7 +24,7 @@
* "edit" = "Drupal\custom_block\CustomBlockTypeFormController",
* "delete" = "Drupal\custom_block\Form\CustomBlockTypeDeleteForm"
* },
- * "list_builder" = "Drupal\custom_block\CustomBlockTypeListBuilder"
+ * "list" = "Drupal\custom_block\CustomBlockTypeListController"
* },
* admin_permission = "administer blocks",
* config_prefix = "type",
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Block/CustomBlockBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Block/CustomBlockBlock.php
index dab9b26..fe7f461 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Block/CustomBlockBlock.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Block/CustomBlockBlock.php
@@ -93,12 +93,6 @@ public function defaultConfiguration() {
'status' => TRUE,
'info' => '',
'view_mode' => 'full',
- // Modify the default max age for custom block blocks: modifications made
- // to them will automatically invalidate corresponding cache tags, thus
- // allowing us to cache custom block blocks forever.
- 'cache' => array(
- 'max_age' => \Drupal\Core\Cache\Cache::PERMANENT,
- ),
);
}
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockListTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockListTest.php
index fa7cc8f..3678a23 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockListTest.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockListTest.php
@@ -12,7 +12,7 @@
/**
* Tests the listing of custom blocks.
*
- * @see \Drupal\block\CustomBlockListBuilder
+ * @see \Drupal\block\CustomBlockListController
*/
class CustomBlockListTest extends WebTestBase {
diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php
index 2dd5cde..d278663 100644
--- a/core/modules/block/lib/Drupal/block/BlockBase.php
+++ b/core/modules/block/lib/Drupal/block/BlockBase.php
@@ -10,10 +10,7 @@
use Drupal\Core\Plugin\PluginBase;
use Drupal\block\BlockInterface;
use Drupal\Component\Utility\Unicode;
-use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Language\Language;
-use Drupal\Core\Cache\Cache;
-use Drupal\Core\Cache\CacheableInterface;
use Drupal\Core\Session\AccountInterface;
/**
@@ -31,7 +28,12 @@
public function __construct(array $configuration, $plugin_id, array $plugin_definition) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
- $this->setConfiguration($configuration);
+ $this->configuration += $this->defaultConfiguration() + array(
+ 'label' => '',
+ 'module' => $plugin_definition['module'],
+ 'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
+ 'cache' => DRUPAL_NO_CACHE,
+ );
}
/**
@@ -45,29 +47,7 @@ public function getConfiguration() {
* {@inheritdoc}
*/
public function setConfiguration(array $configuration) {
- $this->configuration = NestedArray::mergeDeep(
- $this->baseConfigurationDefaults(),
- $this->defaultConfiguration(),
- $configuration
- );
- }
-
- /**
- * Returns generic default configuration for block plugins.
- *
- * @return array
- * An associative array with the default configuration.
- */
- protected function baseConfigurationDefaults() {
- return array(
- 'label' => '',
- 'module' => $this->pluginDefinition['module'],
- 'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
- 'cache' => array(
- 'max_age' => 0,
- 'contexts' => array(),
- ),
- );
+ $this->configuration = $configuration;
}
/**
@@ -128,50 +108,10 @@ public function buildConfigurationForm(array $form, array &$form_state) {
'#default_value' => ($this->configuration['label_display'] === BlockInterface::BLOCK_LABEL_VISIBLE),
'#return_value' => BlockInterface::BLOCK_LABEL_VISIBLE,
);
- // Identical options to the ones for page caching.
- // @see \Drupal\system\Form\PerformanceForm::buildForm()
- $period = array(0, 60, 180, 300, 600, 900, 1800, 2700, 3600, 10800, 21600, 32400, 43200, 86400);
- $period = array_map('format_interval', array_combine($period, $period));
- $period[0] = '<' . t('no caching') . '>';
- $period[\Drupal\Core\Cache\Cache::PERMANENT] = t('Forever');
$form['cache'] = array(
- '#type' => 'details',
- '#title' => t('Cache settings'),
- );
- $form['cache']['max_age'] = array(
- '#type' => 'select',
- '#title' => t('Maximum age'),
- '#description' => t('The maximum time this block may be cached.'),
- '#default_value' => $this->configuration['cache']['max_age'],
- '#options' => $period,
- );
- $contexts = \Drupal::service("cache_contexts")->getLabels();
- // Blocks are always rendered in a "per theme" cache context. No need to
- // show that option to the end user.
- unset($contexts['cache_context.theme']);
- $form['cache']['contexts'] = array(
- '#type' => 'checkboxes',
- '#title' => t('Vary by context'),
- '#description' => t('The contexts this cached block must be varied by.'),
- '#default_value' => $this->configuration['cache']['contexts'],
- '#options' => $contexts,
- '#states' => array(
- 'disabled' => array(
- ':input[name="settings[cache][max_age]"]' => array('value' => (string) 0),
- ),
- ),
+ '#type' => 'value',
+ '#value' => $this->configuration['cache'],
);
- if (count($this->getRequiredCacheContexts()) > 0) {
- // Remove the required cache contexts from the list of contexts a user can
- // choose to modify by: they must always be applied.
- $context_labels = array();
- foreach ($this->getRequiredCacheContexts() as $context) {
- $context_labels[] = $form['cache']['contexts']['#options'][$context];
- unset($form['cache']['contexts']['#options'][$context]);
- }
- $required_context_list = implode(', ', $context_labels);
- $form['cache']['contexts']['#description'] .= ' ' . t('This block is always varied by the following contexts: %required-context-list.', array('%required-context-list' => $required_context_list));
- }
// Add plugin-specific settings for this block type.
$form += $this->blockForm($form, $form_state);
@@ -194,9 +134,6 @@ public function blockForm($form, &$form_state) {
* @see \Drupal\block\BlockBase::blockValidate()
*/
public function validateConfigurationForm(array &$form, array &$form_state) {
- // Transform the #type = checkboxes value to a numerically indexed array.
- $form_state['values']['cache']['contexts'] = array_values(array_filter($form_state['values']['cache']['contexts']));
-
$this->blockValidate($form, $form_state);
}
@@ -219,7 +156,6 @@ public function submitConfigurationForm(array &$form, array &$form_state) {
$this->configuration['label'] = $form_state['values']['label'];
$this->configuration['label_display'] = $form_state['values']['label_display'];
$this->configuration['module'] = $form_state['values']['module'];
- $this->configuration['cache'] = $form_state['values']['cache'];
$this->blockSubmit($form, $form_state);
}
}
@@ -253,59 +189,4 @@ public function getMachineNameSuggestion() {
return $transliterated;
}
- /**
- * Returns the cache contexts required for this block.
- *
- * @return array
- * The required cache contexts IDs.
- */
- protected function getRequiredCacheContexts() {
- return array();
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCacheKeys() {
- // Return the required cache contexts, merged with the user-configured cache
- // contexts, if any.
- return array_merge($this->getRequiredCacheContexts(), $this->configuration['cache']['contexts']);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCacheTags() {
- // If a block plugin's output changes, then it must be able to invalidate a
- // cache tag that affects all instances of this block: across themes and
- // across regions.
- $block_plugin_cache_tag = str_replace(':', '__', $this->getPluginID());
- return array('block_plugin' => array($block_plugin_cache_tag));
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCacheBin() {
- return 'block';
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCacheMaxAge() {
- return (int)$this->configuration['cache']['max_age'];
- }
-
- /**
- * {@inheritdoc}
- */
- public function isCacheable() {
- // Similar to the page cache, a block is cacheable if it has a max age.
- // Blocks that should never be cached can override this method to simply
- // return FALSE.
- $max_age = $this->getCacheMaxAge();
- return $max_age === Cache::PERMANENT || $max_age > 0;
- }
-
}
diff --git a/core/modules/block/lib/Drupal/block/BlockListBuilder.php b/core/modules/block/lib/Drupal/block/BlockListBuilder.php
deleted file mode 100644
index 31b3286..0000000
--- a/core/modules/block/lib/Drupal/block/BlockListBuilder.php
+++ /dev/null
@@ -1,420 +0,0 @@
-blockManager = $block_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('plugin.manager.block')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function load() {
- // If no theme was specified, use the current theme.
- if (!$this->theme) {
- $this->theme = $GLOBALS['theme'];
- }
-
- // Store the region list.
- $this->regions = system_region_list($this->theme, REGIONS_VISIBLE);
-
- // Load only blocks for this theme, and sort them.
- // @todo Move the functionality of _block_rehash() out of the listing page.
- $entities = _block_rehash($this->theme);
-
- // Sort the blocks using \Drupal\block\Entity\Block::sort().
- uasort($entities, array($this->entityType->getClass(), 'sort'));
- return $entities;
- }
-
- /**
- * {@inheritdoc}
- *
- * @param string|null $theme
- * (optional) The theme to display the blocks for. If NULL, the current
- * theme will be used.
- * @param \Symfony\Component\HttpFoundation\Request $request
- * The current request.
- *
- * @return array
- * The block list as a renderable array.
- */
- public function render($theme = NULL, Request $request = NULL) {
- $this->request = $request;
- // If no theme was specified, use the current theme.
- $this->theme = $theme ?: $GLOBALS['theme_key'];
-
- return drupal_get_form($this);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFormId() {
- return 'block_admin_display_form';
- }
-
- /**
- * Implements \Drupal\Core\Form\FormInterface::buildForm().
- *
- * Form constructor for the main block administration form.
- */
- public function buildForm(array $form, array &$form_state) {
- $placement = FALSE;
- if ($this->request->query->has('block-placement')) {
- $placement = $this->request->query->get('block-placement');
- $form['#attached']['js'][] = array(
- 'type' => 'setting',
- 'data' => array('blockPlacement' => $placement),
- );
- }
- $entities = $this->load();
- $form['#theme'] = array('block_list');
- $form['#attached']['library'][] = 'core/drupal.tableheader';
- $form['#attached']['library'][] = 'block/drupal.block';
- $form['#attached']['library'][] = 'block/drupal.block.admin';
- $form['#attributes']['class'][] = 'clearfix';
-
- // Add a last region for disabled blocks.
- $block_regions_with_disabled = $this->regions + array(BlockInterface::BLOCK_REGION_NONE => BlockInterface::BLOCK_REGION_NONE);
- $form['block_regions'] = array(
- '#type' => 'value',
- '#value' => $block_regions_with_disabled,
- );
-
- // Weights range from -delta to +delta, so delta should be at least half
- // of the amount of blocks present. This makes sure all blocks in the same
- // region get an unique weight.
- $weight_delta = round(count($entities) / 2);
-
- // Build the form tree.
- $form['edited_theme'] = array(
- '#type' => 'value',
- '#value' => $this->theme,
- );
- $form['blocks'] = array(
- '#type' => 'table',
- '#header' => array(
- t('Block'),
- t('Category'),
- t('Region'),
- t('Weight'),
- t('Operations'),
- ),
- '#attributes' => array(
- 'id' => 'blocks',
- ),
- );
-
- // Build blocks first for each region.
- foreach ($entities as $entity_id => $entity) {
- $definition = $entity->getPlugin()->getPluginDefinition();
- $blocks[$entity->get('region')][$entity_id] = array(
- 'label' => $entity->label(),
- 'entity_id' => $entity_id,
- 'weight' => $entity->get('weight'),
- 'entity' => $entity,
- 'category' => $definition['category'],
- );
- }
-
- // Loop over each region and build blocks.
- foreach ($block_regions_with_disabled as $region => $title) {
- $form['blocks']['#tabledrag'][] = array(
- 'action' => 'match',
- 'relationship' => 'sibling',
- 'group' => 'block-region-select',
- 'subgroup' => 'block-region-' . $region,
- 'hidden' => FALSE,
- );
- $form['blocks']['#tabledrag'][] = array(
- 'action' => 'order',
- 'relationship' => 'sibling',
- 'group' => 'block-weight',
- 'subgroup' => 'block-weight-' . $region,
- );
-
- $form['blocks'][$region] = array(
- '#attributes' => array(
- 'class' => array('region-title', 'region-title-' . $region),
- 'no_striping' => TRUE,
- ),
- );
- $form['blocks'][$region]['title'] = array(
- '#markup' => $region != BlockInterface::BLOCK_REGION_NONE ? $title : t('Disabled'),
- '#wrapper_attributes' => array(
- 'colspan' => 5,
- ),
- );
-
- $form['blocks'][$region . '-message'] = array(
- '#attributes' => array(
- 'class' => array(
- 'region-message',
- 'region-' . $region . '-message',
- empty($blocks[$region]) ? 'region-empty' : 'region-populated',
- ),
- ),
- );
- $form['blocks'][$region . '-message']['message'] = array(
- '#markup' => '' . t('No blocks in this region') . '',
- '#wrapper_attributes' => array(
- 'colspan' => 5,
- ),
- );
-
- if (isset($blocks[$region])) {
- foreach ($blocks[$region] as $info) {
- $entity_id = $info['entity_id'];
-
- $form['blocks'][$entity_id] = array(
- '#attributes' => array(
- 'class' => array('draggable'),
- ),
- );
- if ($placement && $placement == drupal_html_class($entity_id)) {
- $form['blocks'][$entity_id]['#attributes']['id'] = 'block-placed';
- }
-
- $form['blocks'][$entity_id]['info'] = array(
- '#markup' => String::checkPlain($info['label']),
- '#wrapper_attributes' => array(
- 'class' => array('block'),
- ),
- );
- $form['blocks'][$entity_id]['type'] = array(
- '#markup' => $info['category'],
- );
- $form['blocks'][$entity_id]['region-theme']['region'] = array(
- '#type' => 'select',
- '#default_value' => $region,
- '#empty_value' => BlockInterface::BLOCK_REGION_NONE,
- '#title' => t('Region for @block block', array('@block' => $info['label'])),
- '#title_display' => 'invisible',
- '#options' => $this->regions,
- '#attributes' => array(
- 'class' => array('block-region-select', 'block-region-' . $region),
- ),
- '#parents' => array('blocks', $entity_id, 'region'),
- );
- $form['blocks'][$entity_id]['region-theme']['theme'] = array(
- '#type' => 'hidden',
- '#value' => $this->theme,
- '#parents' => array('blocks', $entity_id, 'theme'),
- );
- $form['blocks'][$entity_id]['weight'] = array(
- '#type' => 'weight',
- '#default_value' => $info['weight'],
- '#delta' => $weight_delta,
- '#title' => t('Weight for @block block', array('@block' => $info['label'])),
- '#title_display' => 'invisible',
- '#attributes' => array(
- 'class' => array('block-weight', 'block-weight-' . $region),
- ),
- );
- $form['blocks'][$entity_id]['operations'] = $this->buildOperations($info['entity']);
- }
- }
- }
-
- // Do not allow disabling the main system content block when it is present.
- if (isset($form['blocks']['system_main']['region'])) {
- $form['blocks']['system_main']['region']['#required'] = TRUE;
- }
-
- $form['actions'] = array(
- '#tree' => FALSE,
- '#type' => 'actions',
- );
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save blocks'),
- '#button_type' => 'primary',
- );
-
- $form['place_blocks']['title'] = array(
- '#type' => 'container',
- '#children' => '' . t('Place blocks') . '
',
- '#attributes' => array(
- 'class' => array(
- 'entity-meta-header',
- ),
- ),
- );
-
- $form['place_blocks']['filter'] = array(
- '#type' => 'search',
- '#title' => t('Filter'),
- '#title_display' => 'invisible',
- '#size' => 30,
- '#placeholder' => t('Filter by block name'),
- '#attributes' => array(
- 'class' => array('block-filter-text'),
- 'data-element' => '.entity-meta',
- 'title' => t('Enter a part of the block name to filter by.'),
- ),
- );
-
- $form['place_blocks']['list']['#type'] = 'container';
- $form['place_blocks']['list']['#attributes']['class'][] = 'entity-meta';
-
- // Sort the plugins first by category, then by label.
- $plugins = $this->blockManager->getDefinitions();
- uasort($plugins, function ($a, $b) {
- if ($a['category'] != $b['category']) {
- return strnatcasecmp($a['category'], $b['category']);
- }
- return strnatcasecmp($a['admin_label'], $b['admin_label']);
- });
- foreach ($plugins as $plugin_id => $plugin_definition) {
- $category = String::checkPlain($plugin_definition['category']);
- $category_key = 'category-' . $category;
- if (!isset($form['place_blocks']['list'][$category_key])) {
- $form['place_blocks']['list'][$category_key] = array(
- '#type' => 'details',
- '#title' => $category,
- '#open' => TRUE,
- 'content' => array(
- '#theme' => 'links',
- '#links' => array(),
- '#attributes' => array(
- 'class' => array(
- 'block-list',
- ),
- ),
- ),
- );
- }
- $form['place_blocks']['list'][$category_key]['content']['#links'][$plugin_id] = array(
- 'title' => $plugin_definition['admin_label'],
- 'href' => 'admin/structure/block/add/' . $plugin_id . '/' . $this->theme,
- 'attributes' => array(
- 'class' => array('use-ajax', 'block-filter-text-source'),
- 'data-accepts' => 'application/vnd.drupal-modal',
- 'data-dialog-options' => Json::encode(array(
- 'width' => 700,
- )),
- ),
- );
- }
- return $form;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
-
- if (isset($operations['edit'])) {
- $operations['edit']['title'] = t('Configure');
- }
-
- return $operations;
- }
-
- /**
- * Implements \Drupal\Core\Form\FormInterface::validateForm().
- */
- public function validateForm(array &$form, array &$form_state) {
- // No validation.
- }
-
- /**
- * Implements \Drupal\Core\Form\FormInterface::submitForm().
- *
- * Form submission handler for the main block administration form.
- */
- public function submitForm(array &$form, array &$form_state) {
- $entities = entity_load_multiple('block', array_keys($form_state['values']['blocks']));
- foreach ($entities as $entity_id => $entity) {
- $entity->set('weight', $form_state['values']['blocks'][$entity_id]['weight']);
- $entity->set('region', $form_state['values']['blocks'][$entity_id]['region']);
- if ($entity->get('region') == BlockInterface::BLOCK_REGION_NONE) {
- $entity->disable();
- }
- else {
- $entity->enable();
- }
- $entity->save();
- }
- drupal_set_message(t('The block settings have been updated.'));
- Cache::invalidateTags(array('content' => TRUE));
- }
-
-}
diff --git a/core/modules/block/lib/Drupal/block/BlockListController.php b/core/modules/block/lib/Drupal/block/BlockListController.php
new file mode 100644
index 0000000..65db261
--- /dev/null
+++ b/core/modules/block/lib/Drupal/block/BlockListController.php
@@ -0,0 +1,420 @@
+blockManager = $block_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('plugin.manager.block')
+ );
+ }
+
+ /**
+ * Overrides \Drupal\Core\Config\Entity\ConfigEntityListController::load().
+ */
+ public function load() {
+ // If no theme was specified, use the current theme.
+ if (!$this->theme) {
+ $this->theme = $GLOBALS['theme'];
+ }
+
+ // Store the region list.
+ $this->regions = system_region_list($this->theme, REGIONS_VISIBLE);
+
+ // Load only blocks for this theme, and sort them.
+ // @todo Move the functionality of _block_rehash() out of the listing page.
+ $entities = _block_rehash($this->theme);
+
+ // Sort the blocks using \Drupal\block\Entity\Block::sort().
+ uasort($entities, array($this->entityType->getClass(), 'sort'));
+ return $entities;
+ }
+
+ /**
+ * Overrides \Drupal\Core\Entity\EntityListController::render().
+ *
+ * @param string|null $theme
+ * (optional) The theme to display the blocks for. If NULL, the current
+ * theme will be used.
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * The current request.
+ *
+ * @return array
+ * The block list as a renderable array.
+ */
+ public function render($theme = NULL, Request $request = NULL) {
+ $this->request = $request;
+ // If no theme was specified, use the current theme.
+ $this->theme = $theme ?: $GLOBALS['theme_key'];
+
+ return drupal_get_form($this);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'block_admin_display_form';
+ }
+
+ /**
+ * Implements \Drupal\Core\Form\FormInterface::buildForm().
+ *
+ * Form constructor for the main block administration form.
+ */
+ public function buildForm(array $form, array &$form_state) {
+ $placement = FALSE;
+ if ($this->request->query->has('block-placement')) {
+ $placement = $this->request->query->get('block-placement');
+ $form['#attached']['js'][] = array(
+ 'type' => 'setting',
+ 'data' => array('blockPlacement' => $placement),
+ );
+ }
+ $entities = $this->load();
+ $form['#theme'] = array('block_list');
+ $form['#attached']['library'][] = 'core/drupal.tableheader';
+ $form['#attached']['library'][] = 'block/drupal.block';
+ $form['#attached']['library'][] = 'block/drupal.block.admin';
+ $form['#attributes']['class'][] = 'clearfix';
+
+ // Add a last region for disabled blocks.
+ $block_regions_with_disabled = $this->regions + array(BlockInterface::BLOCK_REGION_NONE => BlockInterface::BLOCK_REGION_NONE);
+ $form['block_regions'] = array(
+ '#type' => 'value',
+ '#value' => $block_regions_with_disabled,
+ );
+
+ // Weights range from -delta to +delta, so delta should be at least half
+ // of the amount of blocks present. This makes sure all blocks in the same
+ // region get an unique weight.
+ $weight_delta = round(count($entities) / 2);
+
+ // Build the form tree.
+ $form['edited_theme'] = array(
+ '#type' => 'value',
+ '#value' => $this->theme,
+ );
+ $form['blocks'] = array(
+ '#type' => 'table',
+ '#header' => array(
+ t('Block'),
+ t('Category'),
+ t('Region'),
+ t('Weight'),
+ t('Operations'),
+ ),
+ '#attributes' => array(
+ 'id' => 'blocks',
+ ),
+ );
+
+ // Build blocks first for each region.
+ foreach ($entities as $entity_id => $entity) {
+ $definition = $entity->getPlugin()->getPluginDefinition();
+ $blocks[$entity->get('region')][$entity_id] = array(
+ 'label' => $entity->label(),
+ 'entity_id' => $entity_id,
+ 'weight' => $entity->get('weight'),
+ 'entity' => $entity,
+ 'category' => $definition['category'],
+ );
+ }
+
+ // Loop over each region and build blocks.
+ foreach ($block_regions_with_disabled as $region => $title) {
+ $form['blocks']['#tabledrag'][] = array(
+ 'action' => 'match',
+ 'relationship' => 'sibling',
+ 'group' => 'block-region-select',
+ 'subgroup' => 'block-region-' . $region,
+ 'hidden' => FALSE,
+ );
+ $form['blocks']['#tabledrag'][] = array(
+ 'action' => 'order',
+ 'relationship' => 'sibling',
+ 'group' => 'block-weight',
+ 'subgroup' => 'block-weight-' . $region,
+ );
+
+ $form['blocks'][$region] = array(
+ '#attributes' => array(
+ 'class' => array('region-title', 'region-title-' . $region),
+ 'no_striping' => TRUE,
+ ),
+ );
+ $form['blocks'][$region]['title'] = array(
+ '#markup' => $region != BlockInterface::BLOCK_REGION_NONE ? $title : t('Disabled'),
+ '#wrapper_attributes' => array(
+ 'colspan' => 5,
+ ),
+ );
+
+ $form['blocks'][$region . '-message'] = array(
+ '#attributes' => array(
+ 'class' => array(
+ 'region-message',
+ 'region-' . $region . '-message',
+ empty($blocks[$region]) ? 'region-empty' : 'region-populated',
+ ),
+ ),
+ );
+ $form['blocks'][$region . '-message']['message'] = array(
+ '#markup' => '' . t('No blocks in this region') . '',
+ '#wrapper_attributes' => array(
+ 'colspan' => 5,
+ ),
+ );
+
+ if (isset($blocks[$region])) {
+ foreach ($blocks[$region] as $info) {
+ $entity_id = $info['entity_id'];
+
+ $form['blocks'][$entity_id] = array(
+ '#attributes' => array(
+ 'class' => array('draggable'),
+ ),
+ );
+ if ($placement && $placement == drupal_html_class($entity_id)) {
+ $form['blocks'][$entity_id]['#attributes']['id'] = 'block-placed';
+ }
+
+ $form['blocks'][$entity_id]['info'] = array(
+ '#markup' => String::checkPlain($info['label']),
+ '#wrapper_attributes' => array(
+ 'class' => array('block'),
+ ),
+ );
+ $form['blocks'][$entity_id]['type'] = array(
+ '#markup' => $info['category'],
+ );
+ $form['blocks'][$entity_id]['region-theme']['region'] = array(
+ '#type' => 'select',
+ '#default_value' => $region,
+ '#empty_value' => BlockInterface::BLOCK_REGION_NONE,
+ '#title' => t('Region for @block block', array('@block' => $info['label'])),
+ '#title_display' => 'invisible',
+ '#options' => $this->regions,
+ '#attributes' => array(
+ 'class' => array('block-region-select', 'block-region-' . $region),
+ ),
+ '#parents' => array('blocks', $entity_id, 'region'),
+ );
+ $form['blocks'][$entity_id]['region-theme']['theme'] = array(
+ '#type' => 'hidden',
+ '#value' => $this->theme,
+ '#parents' => array('blocks', $entity_id, 'theme'),
+ );
+ $form['blocks'][$entity_id]['weight'] = array(
+ '#type' => 'weight',
+ '#default_value' => $info['weight'],
+ '#delta' => $weight_delta,
+ '#title' => t('Weight for @block block', array('@block' => $info['label'])),
+ '#title_display' => 'invisible',
+ '#attributes' => array(
+ 'class' => array('block-weight', 'block-weight-' . $region),
+ ),
+ );
+ $form['blocks'][$entity_id]['operations'] = $this->buildOperations($info['entity']);
+ }
+ }
+ }
+
+ // Do not allow disabling the main system content block when it is present.
+ if (isset($form['blocks']['system_main']['region'])) {
+ $form['blocks']['system_main']['region']['#required'] = TRUE;
+ }
+
+ $form['actions'] = array(
+ '#tree' => FALSE,
+ '#type' => 'actions',
+ );
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save blocks'),
+ '#button_type' => 'primary',
+ );
+
+ $form['place_blocks']['title'] = array(
+ '#type' => 'container',
+ '#children' => '' . t('Place blocks') . '
',
+ '#attributes' => array(
+ 'class' => array(
+ 'entity-meta-header',
+ ),
+ ),
+ );
+
+ $form['place_blocks']['filter'] = array(
+ '#type' => 'search',
+ '#title' => t('Filter'),
+ '#title_display' => 'invisible',
+ '#size' => 30,
+ '#placeholder' => t('Filter by block name'),
+ '#attributes' => array(
+ 'class' => array('block-filter-text'),
+ 'data-element' => '.entity-meta',
+ 'title' => t('Enter a part of the block name to filter by.'),
+ ),
+ );
+
+ $form['place_blocks']['list']['#type'] = 'container';
+ $form['place_blocks']['list']['#attributes']['class'][] = 'entity-meta';
+
+ // Sort the plugins first by category, then by label.
+ $plugins = $this->blockManager->getDefinitions();
+ uasort($plugins, function ($a, $b) {
+ if ($a['category'] != $b['category']) {
+ return strnatcasecmp($a['category'], $b['category']);
+ }
+ return strnatcasecmp($a['admin_label'], $b['admin_label']);
+ });
+ foreach ($plugins as $plugin_id => $plugin_definition) {
+ $category = String::checkPlain($plugin_definition['category']);
+ $category_key = 'category-' . $category;
+ if (!isset($form['place_blocks']['list'][$category_key])) {
+ $form['place_blocks']['list'][$category_key] = array(
+ '#type' => 'details',
+ '#title' => $category,
+ '#open' => TRUE,
+ 'content' => array(
+ '#theme' => 'links',
+ '#links' => array(),
+ '#attributes' => array(
+ 'class' => array(
+ 'block-list',
+ ),
+ ),
+ ),
+ );
+ }
+ $form['place_blocks']['list'][$category_key]['content']['#links'][$plugin_id] = array(
+ 'title' => $plugin_definition['admin_label'],
+ 'href' => 'admin/structure/block/add/' . $plugin_id . '/' . $this->theme,
+ 'attributes' => array(
+ 'class' => array('use-ajax', 'block-filter-text-source'),
+ 'data-accepts' => 'application/vnd.drupal-modal',
+ 'data-dialog-options' => Json::encode(array(
+ 'width' => 700,
+ )),
+ ),
+ );
+ }
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+
+ if (isset($operations['edit'])) {
+ $operations['edit']['title'] = t('Configure');
+ }
+
+ return $operations;
+ }
+
+ /**
+ * Implements \Drupal\Core\Form\FormInterface::validateForm().
+ */
+ public function validateForm(array &$form, array &$form_state) {
+ // No validation.
+ }
+
+ /**
+ * Implements \Drupal\Core\Form\FormInterface::submitForm().
+ *
+ * Form submission handler for the main block administration form.
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ $entities = entity_load_multiple('block', array_keys($form_state['values']['blocks']));
+ foreach ($entities as $entity_id => $entity) {
+ $entity->set('weight', $form_state['values']['blocks'][$entity_id]['weight']);
+ $entity->set('region', $form_state['values']['blocks'][$entity_id]['region']);
+ if ($entity->get('region') == BlockInterface::BLOCK_REGION_NONE) {
+ $entity->disable();
+ }
+ else {
+ $entity->enable();
+ }
+ $entity->save();
+ }
+ drupal_set_message(t('The block settings have been updated.'));
+ Cache::invalidateTags(array('content' => TRUE));
+ }
+
+}
diff --git a/core/modules/block/lib/Drupal/block/BlockPluginInterface.php b/core/modules/block/lib/Drupal/block/BlockPluginInterface.php
index 4f6bdc2..047efd9 100644
--- a/core/modules/block/lib/Drupal/block/BlockPluginInterface.php
+++ b/core/modules/block/lib/Drupal/block/BlockPluginInterface.php
@@ -7,7 +7,6 @@
namespace Drupal\block;
-use Drupal\Core\Cache\CacheableInterface;
use Drupal\Component\Plugin\PluginInspectionInterface;
use Drupal\Component\Plugin\ConfigurablePluginInterface;
use Drupal\Core\Plugin\PluginFormInterface;
@@ -21,7 +20,7 @@
* brif references to the important components that are not coupled to the
* interface.
*/
-interface BlockPluginInterface extends ConfigurablePluginInterface, PluginFormInterface, PluginInspectionInterface, CacheableInterface {
+interface BlockPluginInterface extends ConfigurablePluginInterface, PluginFormInterface, PluginInspectionInterface {
/**
* Indicates whether the block should be shown.
diff --git a/core/modules/block/lib/Drupal/block/BlockViewBuilder.php b/core/modules/block/lib/Drupal/block/BlockViewBuilder.php
index a6a925a..a076dc9 100644
--- a/core/modules/block/lib/Drupal/block/BlockViewBuilder.php
+++ b/core/modules/block/lib/Drupal/block/BlockViewBuilder.php
@@ -7,9 +7,7 @@
namespace Drupal\block;
-use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\String;
-use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityViewBuilder;
use Drupal\Core\Entity\EntityViewBuilderInterface;
use Drupal\Core\Entity\EntityInterface;
@@ -45,126 +43,61 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
$plugin_id = $plugin->getPluginId();
$base_id = $plugin->getBasePluginId();
$derivative_id = $plugin->getDerivativeId();
- $configuration = $plugin->getConfiguration();
- // Create the render array for the block as a whole.
- // @see template_preprocess_block().
- $build[$entity_id] = array(
- '#theme' => 'block',
- '#attributes' => array(),
- // All blocks get a "Configure block" contextual link.
- '#contextual_links' => array(
- 'block' => array(
- 'route_parameters' => array('block' => $entity->id()),
+ if ($content = $plugin->build()) {
+ $configuration = $plugin->getConfiguration();
+
+ // Create the render array for the block as a whole.
+ // @see template_preprocess_block().
+ $build[$key] = array(
+ '#theme' => 'block',
+ '#attributes' => array(),
+ '#contextual_links' => array(
+ 'block' => array(
+ 'route_parameters' => array('block' => $entity_id),
+ ),
),
- ),
- '#weight' => $entity->get('weight'),
- '#configuration' => $configuration,
- '#plugin_id' => $plugin_id,
- '#base_plugin_id' => $base_id,
- '#derivative_plugin_id' => $derivative_id,
- // @todo Remove after fixing http://drupal.org/node/1989568.
- '#block' => $entity,
- );
- $build[$entity_id]['#configuration']['label'] = check_plain($configuration['label']);
-
- // Set cache tags; these always need to be set, whether the block is
- // cacheable or not, so that the page cache is correctly informed.
- $default_cache_tags = array(
- 'content' => TRUE,
- 'block_view' => TRUE,
- 'block' => array($entity->id()),
- );
- $build[$entity_id]['#cache']['tags'] = NestedArray::mergeDeep($default_cache_tags, $plugin->getCacheTags());
-
-
- if ($plugin->isCacheable()) {
- $build[$entity_id]['#pre_render'][] = array($this, 'buildBlock');
- // Generic cache keys, with the block plugin's custom keys appended
- // (usually cache context keys like 'cache_context.user.roles').
- $default_cache_keys = array(
- 'entity_view',
- 'block',
- $entity->id(),
- $entity->langcode,
- // Blocks are always rendered in a "per theme" cache context.
- 'cache_context.theme',
- );
- $max_age = $plugin->getCacheMaxAge();
- $build[$entity_id]['#cache'] += array(
- 'keys' => array_merge($default_cache_keys, $plugin->getCacheKeys()),
- 'bin' => $plugin->getCacheBin(),
- 'expire' => ($max_age === Cache::PERMANENT) ? Cache::PERMANENT : REQUEST_TIME + $max_age,
+ '#configuration' => $configuration,
+ '#plugin_id' => $plugin_id,
+ '#base_plugin_id' => $base_id,
+ '#derivative_plugin_id' => $derivative_id,
);
+ $build[$key]['#configuration']['label'] = String::checkPlain($configuration['label']);
+
+ // Place the $content returned by the block plugin into a 'content'
+ // child element, as a way to allow the plugin to have complete control
+ // of its properties and rendering (e.g., its own #theme) without
+ // conflicting with the properties used above, or alternate ones used
+ // by alternate block rendering approaches in contrib (e.g., Panels).
+ // However, the use of a child element is an implementation detail of
+ // this particular block rendering approach. Semantically, the content
+ // returned by the plugin "is the" block, and in particular,
+ // #attributes and #contextual_links is information about the *entire*
+ // block. Therefore, we must move these properties from $content and
+ // merge them into the top-level element.
+ foreach (array('#attributes', '#contextual_links') as $property) {
+ if (isset($content[$property])) {
+ $build[$key][$property] += $content[$property];
+ unset($content[$property]);
+ }
+ }
+ $build[$key]['content'] = $content;
}
else {
- $build[$entity_id] = $this->buildBlock($build[$entity_id]);
+ $build[$key] = array();
}
+ $this->moduleHandler()->alter(array('block_view', "block_view_$base_id"), $build[$key], $plugin);
+
// @todo Remove after fixing http://drupal.org/node/1989568.
$build[$key]['#block'] = $entity;
-
- // Don't run in ::buildBlock() to ensure cache keys can be altered. If an
- // alter hook wants to modify the block contents, it can append another
- // #pre_render hook.
- $this->moduleHandler()->alter(array('block_view', "block_view_$base_id"), $build[$entity_id], $plugin);
}
return $build;
}
/**
- * #pre_render callback for building a block.
- *
- * Renders the content using the provided block plugin, and then:
- * - if there is no content, aborts rendering, and makes sure the block won't
- * be rendered.
- * - if there is content, moves the contextual links from the block content to
- * the block itself.
- */
- public function buildBlock($build) {
- $content = $build['#block']->getPlugin()->build();
- if (!empty($content)) {
- // Place the $content returned by the block plugin into a 'content' child
- // element, as a way to allow the plugin to have complete control of its
- // properties and rendering (e.g., its own #theme) without conflicting
- // with the properties used above, or alternate ones used by alternate
- // block rendering approaches in contrib (e.g., Panels). However, the use
- // of a child element is an implementation detail of this particular block
- // rendering approach. Semantically, the content returned by the plugin
- // "is the" block, and in particular, #attributes and #contextual_links is
- // information about the *entire* block. Therefore, we must move these
- // properties from $content and merge them into the top-level element.
- foreach (array('#attributes', '#contextual_links') as $property) {
- if (isset($content[$property])) {
- $build[$property] += $content[$property];
- unset($content[$property]);
- }
- }
- $build['content'] = $content;
- }
- else {
- // Abort rendering: render as the empty string and ensure this block is
- // render cached, so we can avoid the work of having to repeatedly
- // determine whether the block is empty. E.g. modifying or adding entities
- // could cause the block to no longer be empty.
- $build = array(
- '#markup' => '',
- '#cache' => $build['#cache'],
- );
- }
- return $build;
- }
-
- /**
* {@inheritdoc}
*/
- public function resetCache(array $entities = NULL) {
- if (isset($entities)) {
- Cache::invalidateTags(array('block' => array_keys($entities)));
- }
- else {
- Cache::invalidateTags(array('block_view' => TRUE));
- }
- }
+ public function resetCache(array $ids = NULL) { }
}
diff --git a/core/modules/block/lib/Drupal/block/Controller/BlockListController.php b/core/modules/block/lib/Drupal/block/Controller/BlockListController.php
index 72aa445..2852970 100644
--- a/core/modules/block/lib/Drupal/block/Controller/BlockListController.php
+++ b/core/modules/block/lib/Drupal/block/Controller/BlockListController.php
@@ -8,6 +8,7 @@
namespace Drupal\block\Controller;
use Drupal\Core\Entity\Controller\EntityListController;
+use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
/**
@@ -28,7 +29,7 @@ class BlockListController extends EntityListController {
*/
public function listing($theme = NULL, Request $request = NULL) {
$theme = $theme ?: $this->config('system.theme')->get('default');
- return $this->entityManager()->getListBuilder('block')->render($theme, $request);
+ return $this->entityManager()->getListController('block')->render($theme, $request);
}
}
diff --git a/core/modules/block/lib/Drupal/block/Entity/Block.php b/core/modules/block/lib/Drupal/block/Entity/Block.php
index 6caab04..ea3a98a 100644
--- a/core/modules/block/lib/Drupal/block/Entity/Block.php
+++ b/core/modules/block/lib/Drupal/block/Entity/Block.php
@@ -7,7 +7,6 @@
namespace Drupal\block\Entity;
-use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\block\BlockPluginBag;
use Drupal\block\BlockInterface;
@@ -23,7 +22,7 @@
* controllers = {
* "access" = "Drupal\block\BlockAccessController",
* "view_builder" = "Drupal\block\BlockViewBuilder",
- * "list_builder" = "Drupal\block\BlockListBuilder",
+ * "list" = "Drupal\block\BlockListController",
* "form" = {
* "default" = "Drupal\block\BlockFormController",
* "delete" = "Drupal\block\Form\BlockDeleteForm"
@@ -148,32 +147,6 @@ public function toArray() {
}
/**
- * {@inheritdoc}
- */
- public function postSave(EntityStorageControllerInterface $storage_controller, $update = TRUE) {
- parent::postSave($storage_controller, $update);
-
- if ($update) {
- Cache::invalidateTags(array('block' => $this->id()));
- }
- // When placing a new block, invalidate all cache entries for this theme,
- // since any page that uses this theme might be affected.
- else {
- // @todo Replace with theme cache tag: https://drupal.org/node/2185617
- Cache::invalidateTags(array('content' => TRUE));
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public static function postDelete(EntityStorageControllerInterface $storage_controller, array $entities) {
- parent::postDelete($storage_controller, $entities);
-
- Cache::invalidateTags(array('block' => array_keys($entities)));
- }
-
- /**
* Sorts active blocks by weight; sorts inactive blocks by name.
*/
public static function sort($a, $b) {
diff --git a/core/modules/block/lib/Drupal/block/Plugin/views/display/Block.php b/core/modules/block/lib/Drupal/block/Plugin/views/display/Block.php
index 94bea95..657b635 100644
--- a/core/modules/block/lib/Drupal/block/Plugin/views/display/Block.php
+++ b/core/modules/block/lib/Drupal/block/Plugin/views/display/Block.php
@@ -46,6 +46,7 @@ protected function defineOptions() {
$options['block_description'] = array('default' => '', 'translatable' => TRUE);
$options['block_category'] = array('default' => 'Lists (Views)', 'translatable' => TRUE);
+ $options['block_caching'] = array('default' => DRUPAL_NO_CACHE);
$options['block_hide_empty'] = array('default' => FALSE);
$options['allow'] = array(
@@ -130,6 +131,13 @@ public function optionsSummary(&$categories, &$options) {
'value' => empty($filtered_allow) ? t('None') : t('Items per page'),
);
+ $types = $this->blockCachingModes();
+ $options['block_caching'] = array(
+ 'category' => 'other',
+ 'title' => t('Block caching'),
+ 'value' => $types[$this->getCacheType()],
+ );
+
$options['block_hide_empty'] = array(
'category' => 'other',
'title' => t('Hide block if the view output is empty'),
@@ -138,6 +146,33 @@ public function optionsSummary(&$categories, &$options) {
}
/**
+ * Provide a list of core's block caching modes.
+ */
+ protected function blockCachingModes() {
+ return array(
+ DRUPAL_NO_CACHE => t('Do not cache'),
+ DRUPAL_CACHE_GLOBAL => t('Cache once for everything (global)'),
+ DRUPAL_CACHE_PER_PAGE => t('Per page'),
+ DRUPAL_CACHE_PER_ROLE => t('Per role'),
+ DRUPAL_CACHE_PER_ROLE | DRUPAL_CACHE_PER_PAGE => t('Per role per page'),
+ DRUPAL_CACHE_PER_USER => t('Per user'),
+ DRUPAL_CACHE_PER_USER | DRUPAL_CACHE_PER_PAGE => t('Per user per page'),
+ );
+ }
+
+ /**
+ * Provide a single method to figure caching type, keeping a sensible default
+ * for when it's unset.
+ */
+ public function getCacheType() {
+ $cache_type = $this->getOption('block_caching');
+ if (empty($cache_type)) {
+ $cache_type = DRUPAL_NO_CACHE;
+ }
+ return $cache_type;
+ }
+
+ /**
* Provide the default form for setting options.
*/
public function buildOptionsForm(&$form, &$form_state) {
@@ -161,6 +196,16 @@ public function buildOptionsForm(&$form, &$form_state) {
'#default_value' => $this->getOption('block_category'),
);
break;
+ case 'block_caching':
+ $form['#title'] .= t('Block caching type');
+
+ $form['block_caching'] = array(
+ '#type' => 'radios',
+ '#description' => t("This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed."),
+ '#options' => $this->blockCachingModes(),
+ '#default_value' => $this->getCacheType(),
+ );
+ break;
case 'block_hide_empty':
$form['#title'] .= t('Block empty settings');
@@ -206,6 +251,7 @@ public function submitOptionsForm(&$form, &$form_state) {
switch ($form_state['section']) {
case 'block_description':
case 'block_category':
+ case 'block_caching':
case 'allow':
case 'block_hide_empty':
$this->setOption($form_state['section'], $form_state['values'][$form_state['section']]);
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php
index ce78720..7414efd 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockCacheTest.php
@@ -61,13 +61,10 @@ function setUp() {
}
/**
- * Test "cache_context.user.roles" cache context.
+ * Test DRUPAL_CACHE_PER_ROLE.
*/
function testCachePerRole() {
- $this->setBlockCacheConfig(array(
- 'max_age' => 600,
- 'contexts' => array('cache_context.user.roles'),
- ));
+ $this->setCacheMode(DRUPAL_CACHE_PER_ROLE);
// Enable our test block. Set some content for it to display.
$current_content = $this->randomName();
@@ -111,13 +108,10 @@ function testCachePerRole() {
}
/**
- * Test a cacheable block without any cache context.
+ * Test DRUPAL_CACHE_GLOBAL.
*/
function testCacheGlobal() {
- $this->setBlockCacheConfig(array(
- 'max_age' => 600,
- ));
-
+ $this->setCacheMode(DRUPAL_CACHE_GLOBAL);
$current_content = $this->randomName();
\Drupal::state()->set('block_test.content', $current_content);
@@ -130,21 +124,18 @@ function testCacheGlobal() {
$this->drupalLogout();
$this->drupalGet('user');
- $this->assertText($old_content, 'Block content served from cache.');
+ $this->assertText($old_content, 'Block content served from global cache.');
}
/**
- * Test non-cacheable block.
+ * Test DRUPAL_NO_CACHE.
*/
function testNoCache() {
- $this->setBlockCacheConfig(array(
- 'max_age' => 0,
- ));
-
+ $this->setCacheMode(DRUPAL_NO_CACHE);
$current_content = $this->randomName();
\Drupal::state()->set('block_test.content', $current_content);
- // If max_age = 0 has no effect, the next request would be cached.
+ // If DRUPAL_NO_CACHE has no effect, the next request would be cached.
$this->drupalGet('');
$this->assertText($current_content, 'Block content displays.');
@@ -152,18 +143,14 @@ function testNoCache() {
$current_content = $this->randomName();
\Drupal::state()->set('block_test.content', $current_content);
$this->drupalGet('');
- $this->assertText($current_content, 'Maximum age of zero prevents blocks from being cached.');
+ $this->assertText($current_content, 'DRUPAL_NO_CACHE prevents blocks from being cached.');
}
/**
- * Test "cache_context.user" cache context.
+ * Test DRUPAL_CACHE_PER_USER.
*/
function testCachePerUser() {
- $this->setBlockCacheConfig(array(
- 'max_age' => 600,
- 'contexts' => array('cache_context.user'),
- ));
-
+ $this->setCacheMode(DRUPAL_CACHE_PER_USER);
$current_content = $this->randomName();
\Drupal::state()->set('block_test.content', $current_content);
$this->drupalLogin($this->normal_user);
@@ -188,14 +175,10 @@ function testCachePerUser() {
}
/**
- * Test "cache_context.url" cache context.
+ * Test DRUPAL_CACHE_PER_PAGE.
*/
function testCachePerPage() {
- $this->setBlockCacheConfig(array(
- 'max_age' => 600,
- 'contexts' => array('cache_context.url'),
- ));
-
+ $this->setCacheMode(DRUPAL_CACHE_PER_PAGE);
$current_content = $this->randomName();
\Drupal::state()->set('block_test.content', $current_content);
@@ -213,11 +196,10 @@ function testCachePerPage() {
}
/**
- * Private helper method to set the test block's cache configuration.
+ * Private helper method to set the test block's cache mode.
*/
- private function setBlockCacheConfig($cache_config) {
- $block = $this->block->getPlugin();
- $block->setConfigurationValue('cache', $cache_config);
+ private function setCacheMode($cache_mode) {
+ $this->block->getPlugin()->setConfigurationValue('cache', $cache_mode);
$this->block->save();
}
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php
index 5e7d9d0..a694b4e 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockInterfaceTest.php
@@ -45,13 +45,10 @@ public function testBlockInterface() {
);
$expected_configuration = array(
'label' => 'Custom Display Message',
+ 'display_message' => 'no message set',
'module' => 'block_test',
'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
- 'cache' => array(
- 'max_age' => 0,
- 'contexts' => array(),
- ),
- 'display_message' => 'no message set',
+ 'cache' => DRUPAL_NO_CACHE,
);
// Initial configuration of the block at construction time.
$display_block = $manager->createInstance('test_block_instantiation', $configuration);
@@ -63,12 +60,6 @@ public function testBlockInterface() {
$this->assertIdentical($display_block->getConfiguration(), $expected_configuration, 'The block configuration was updated correctly.');
$definition = $display_block->getPluginDefinition();
- $period = array(0, 60, 180, 300, 600, 900, 1800, 2700, 3600, 10800, 21600, 32400, 43200, 86400);
- $period = array_map('format_interval', array_combine($period, $period));
- $period[0] = '<' . t('no caching') . '>';
- $period[\Drupal\Core\Cache\Cache::PERMANENT] = t('Forever');
- $contexts = \Drupal::service("cache_contexts")->getLabels();
- unset($contexts['cache_context.theme']);
$expected_form = array(
'module' => array(
'#type' => 'value',
@@ -93,27 +84,8 @@ public function testBlockInterface() {
'#return_value' => 'visible',
),
'cache' => array(
- '#type' => 'details',
- '#title' => t('Cache settings'),
- 'max_age' => array(
- '#type' => 'select',
- '#title' => t('Maximum age'),
- '#description' => t('The maximum time this block may be cached.'),
- '#default_value' => 0,
- '#options' => $period,
- ),
- 'contexts' => array(
- '#type' => 'checkboxes',
- '#title' => t('Vary by context'),
- '#description' => t('The contexts this cached block must be varied by.'),
- '#default_value' => array(),
- '#options' => $contexts,
- '#states' => array(
- 'disabled' => array(
- ':input[name="settings[cache][max_age]"]' => array('value' => (string) 0),
- ),
- ),
- ),
+ '#type' => 'value',
+ '#value' => DRUPAL_NO_CACHE,
),
'display_message' => array(
'#type' => 'textfield',
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockRenderOrderTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockRenderOrderTest.php
index 1a7ea82..0521aa9 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockRenderOrderTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockRenderOrderTest.php
@@ -48,24 +48,21 @@ function testBlockRenderOrder() {
'stark_powered' => array(
'weight' => '-3',
'id' => 'stark_powered',
- 'label' => 'Test block A',
),
'stark_by' => array(
'weight' => '3',
'id' => 'stark_by',
- 'label' => 'Test block C',
),
'stark_drupal' => array(
'weight' => '3',
'id' => 'stark_drupal',
- 'label' => 'Test block B',
),
);
// Place the test blocks.
foreach ($test_blocks as $test_block) {
$this->drupalPlaceBlock('system_powered_by_block', array(
- 'label' => $test_block['label'],
+ 'label' => 'Test Block',
'region' => $region,
'weight' => $test_block['weight'],
'id' => $test_block['id'],
@@ -84,6 +81,6 @@ function testBlockRenderOrder() {
}
}
$this->assertTrue($position['stark_powered'] < $position['stark_by'], 'Blocks with different weight are rendered in the correct order.');
- $this->assertTrue($position['stark_drupal'] < $position['stark_by'], 'Blocks with identical weight are rendered in alphabetical order.');
+ $this->assertTrue($position['stark_drupal'] < $position['stark_by'], 'Blocks with identical weight are rendered in reverse alphabetical order.');
}
}
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php
index e63fb2b..aff9d70 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockStorageUnitTest.php
@@ -56,6 +56,7 @@ public function testBlockCRUD() {
// Run each test method in the same installation.
$this->createTests();
$this->loadTests();
+ $this->renderTests();
$this->deleteTests();
}
@@ -102,10 +103,7 @@ protected function createTests() {
'label' => '',
'module' => 'block_test',
'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
- 'cache' => array(
- 'max_age' => 0,
- 'contexts' => array(),
- ),
+ 'cache' => DRUPAL_NO_CACHE,
),
'visibility' => NULL,
);
@@ -115,7 +113,7 @@ protected function createTests() {
}
/**
- * Tests the loading of blocks.
+ * Tests the rendering of blocks.
*/
protected function loadTests() {
$entity = $this->controller->load('test_block');
@@ -130,6 +128,57 @@ protected function loadTests() {
}
/**
+ * Tests the rendering of blocks.
+ */
+ protected function renderTests() {
+ // Test the rendering of a block.
+ $entity = entity_load('block', 'test_block');
+ $output = entity_view($entity, 'block');
+ $expected = array();
+ $expected[] = '';
+ $expected[] = ' ';
+ $expected[] = ' ';
+ $expected[] = '';
+ $expected[] = '
';
+ $expected[] = ' ';
+ $expected[] = '
';
+ $expected[] = '
';
+ $expected[] = '';
+ $expected_output = implode("\n", $expected);
+ $this->assertEqual(drupal_render($output), $expected_output);
+
+ // Reset the HTML IDs so that the next render is not affected.
+ drupal_static_reset('drupal_html_id');
+
+ // Test the rendering of a block with a given title.
+ $entity = $this->controller->create(array(
+ 'id' => 'test_block2',
+ 'theme' => 'stark',
+ 'plugin' => 'test_html',
+ 'settings' => array(
+ 'label' => 'Powered by Bananas',
+ ),
+ ));
+ $entity->save();
+ $output = entity_view($entity, 'block');
+ $expected = array();
+ $expected[] = '';
+ $expected[] = ' ';
+ $expected[] = '
Powered by Bananas
';
+ $expected[] = ' ';
+ $expected[] = '';
+ $expected[] = '
';
+ $expected[] = ' ';
+ $expected[] = '
';
+ $expected[] = '
';
+ $expected[] = '';
+ $expected_output = implode("\n", $expected);
+ $this->assertEqual(drupal_render($output), $expected_output);
+ // Clean up this entity.
+ $entity->delete();
+ }
+
+ /**
* Tests the deleting of blocks.
*/
protected function deleteTests() {
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php
index cc25986..e7b99e1 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php
@@ -7,7 +7,6 @@
namespace Drupal\block\Tests;
-use Drupal\Core\Cache\Cache;
use Drupal\simpletest\WebTestBase;
/**
@@ -250,106 +249,35 @@ function moveBlockToRegion(array $block, $region) {
}
/**
- * Test that cache tags are properly set and bubbled up to the page cache.
- *
- * Verify that invalidation of these cache tags works:
- * - "block:"
- * - "block_plugin:"
+ * Test _block_rehash().
*/
- public function testBlockCacheTags() {
- // The page cache only works for anonymous users.
- $this->drupalLogout();
+ function testBlockRehash() {
+ \Drupal::moduleHandler()->install(array('block_test'));
+ $this->assertTrue(\Drupal::moduleHandler()->moduleExists('block_test'), 'Test block module enabled.');
- // Enable page caching.
- $config = \Drupal::config('system.performance');
- $config->set('cache.page.use_internal', 1);
- $config->set('cache.page.max_age', 300);
- $config->save();
-
- // Place the "Powered by Drupal" block.
- $block = $this->drupalPlaceBlock('system_powered_by_block', array('id' => 'powered', 'cache' => array('max_age' => 315360000)));
-
- // Prime the page cache.
- $this->drupalGet('');
- $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
-
- // Verify a cache hit, but also the presence of the correct cache tags in
- // both the page and block caches.
- $this->drupalGet('');
- $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
- $cid_parts = array(url('', array('absolute' => TRUE)), 'html');
- $cid = sha1(implode(':', $cid_parts));
- $cache_entry = \Drupal::cache('page')->get($cid);
- $expected_cache_tags = array(
- 'content:1',
- 'block_view:1',
- 'block:powered',
- 'block_plugin:system_powered_by_block',
- );
- $this->assertIdentical($cache_entry->tags, $expected_cache_tags);
- $cache_entry = \Drupal::cache('block')->get('entity_view:block:powered:en:stark');
- $this->assertIdentical($cache_entry->tags, $expected_cache_tags);
+ // Clear the block cache to load the block_test module's block definitions.
+ $this->container->get('plugin.manager.block')->clearCachedDefinitions();
- // The "Powered by Drupal" block is modified; verify a cache miss.
- $block->set('region', 'content');
+ // Add a test block.
+ $block = array();
+ $block['id'] = 'test_cache';
+ $block['theme'] = \Drupal::config('system.theme')->get('default');
+ $block['region'] = 'header';
+ $block = $this->drupalPlaceBlock('test_cache', array('region' => 'header'));
+
+ // Our test block's caching should default to DRUPAL_CACHE_PER_ROLE.
+ $settings = $block->get('settings');
+ $this->assertEqual($settings['cache'], DRUPAL_CACHE_PER_ROLE, 'Test block cache mode defaults to DRUPAL_CACHE_PER_ROLE.');
+
+ // Disable caching for this block.
+ $block->getPlugin()->setConfigurationValue('cache', DRUPAL_NO_CACHE);
$block->save();
- $this->drupalGet('');
- $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
-
- // Now we should have a cache hit again.
- $this->drupalGet('');
- $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
-
- // Place the "Powered by Drupal" block another time; verify a cache miss.
- $block_2 = $this->drupalPlaceBlock('system_powered_by_block', array('id' => 'powered-2', 'cache' => array('max_age' => 315360000)));
- $this->drupalGet('');
- $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
-
- // Verify a cache hit, but also the presence of the correct cache tags.
- $this->drupalGet('');
- $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
- $cid_parts = array(url('', array('absolute' => TRUE)), 'html');
- $cid = sha1(implode(':', $cid_parts));
- $cache_entry = \Drupal::cache('page')->get($cid);
- $expected_cache_tags = array(
- 'content:1',
- 'block_view:1',
- 'block:powered-2',
- 'block:powered',
- 'block_plugin:system_powered_by_block',
- );
- $this->assertEqual($cache_entry->tags, $expected_cache_tags);
- $expected_cache_tags = array(
- 'content:1',
- 'block_view:1',
- 'block:powered',
- 'block_plugin:system_powered_by_block',
- );
- $cache_entry = \Drupal::cache('block')->get('entity_view:block:powered:en:stark');
- $this->assertIdentical($cache_entry->tags, $expected_cache_tags);
- $expected_cache_tags = array(
- 'content:1',
- 'block_view:1',
- 'block:powered-2',
- 'block_plugin:system_powered_by_block',
- );
- $cache_entry = \Drupal::cache('block')->get('entity_view:block:powered-2:en:stark');
- $this->assertIdentical($cache_entry->tags, $expected_cache_tags);
-
- // The plugin providing the "Powered by Drupal" block is modified; verify a
- // cache miss.
- Cache::invalidateTags(array('block_plugin:system_powered_by_block'));
- $this->drupalGet('');
- $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
-
- // Now we should have a cache hit again.
- $this->drupalGet('');
- $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
-
- // Delete the "Powered by Drupal" blocks; verify a cache miss.
- entity_delete_multiple('block', array('powered', 'powered-2'));
- $this->drupalGet('');
- $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
+ // Flushing all caches should call _block_rehash().
+ $this->resetAll();
+ // Verify that block is updated with the new caching mode.
+ $block = entity_load('block', $block->id());
+ $settings = $block->get('settings');
+ $this->assertEqual($settings['cache'], DRUPAL_NO_CACHE, "Test block's database entry updated to DRUPAL_NO_CACHE.");
}
}
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockViewBuilderTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockViewBuilderTest.php
deleted file mode 100644
index aa7dd2e..0000000
--- a/core/modules/block/lib/Drupal/block/Tests/BlockViewBuilderTest.php
+++ /dev/null
@@ -1,346 +0,0 @@
- 'Block rendering',
- 'description' => 'Tests the block view builder.',
- 'group' => 'Block',
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function setUp() {
- parent::setUp();
-
- $this->controller = $this->container
- ->get('entity.manager')
- ->getStorageController('block');
-
- \Drupal::state()->set('block_test.content', 'Llamas > unicorns!');
-
- // Create a block with only required values.
- $this->block = $this->controller->create(array(
- 'id' => 'test_block',
- 'theme' => 'stark',
- 'plugin' => 'test_cache',
- ));
- $this->block->save();
-
- $this->container->get('cache.block')->deleteAll();
- }
-
- /**
- * Tests the rendering of blocks.
- */
- public function testBasicRendering() {
- \Drupal::state()->set('block_test.content', '');
-
- $entity = $this->controller->create(array(
- 'id' => 'test_block1',
- 'theme' => 'stark',
- 'plugin' => 'test_html',
- ));
- $entity->save();
-
- // Test the rendering of a block.
- $entity = entity_load('block', 'test_block1');
- $output = entity_view($entity, 'block');
- $expected = array();
- $expected[] = '';
- $expected[] = ' ';
- $expected[] = ' ';
- $expected[] = '';
- $expected[] = '
';
- $expected[] = ' ';
- $expected[] = '
';
- $expected[] = '
';
- $expected[] = '';
- $expected_output = implode("\n", $expected);
- $this->assertEqual(drupal_render($output), $expected_output);
-
- // Reset the HTML IDs so that the next render is not affected.
- drupal_static_reset('drupal_html_id');
-
- // Test the rendering of a block with a given title.
- $entity = $this->controller->create(array(
- 'id' => 'test_block2',
- 'theme' => 'stark',
- 'plugin' => 'test_html',
- 'settings' => array(
- 'label' => 'Powered by Bananas',
- ),
- ));
- $entity->save();
- $output = entity_view($entity, 'block');
- $expected = array();
- $expected[] = '';
- $expected[] = ' ';
- $expected[] = '
Powered by Bananas
';
- $expected[] = ' ';
- $expected[] = '';
- $expected[] = '
';
- $expected[] = ' ';
- $expected[] = '
';
- $expected[] = '
';
- $expected[] = '';
- $expected_output = implode("\n", $expected);
- $this->assertEqual(drupal_render($output), $expected_output);
- }
-
- /**
- * Tests block render cache handling.
- */
- public function testBlockViewBuilderCache() {
- // Verify cache handling for a non-empty block.
- $this->verifyRenderCacheHandling();
-
- // Create an empty block.
- $this->block = $this->controller->create(array(
- 'id' => 'test_block',
- 'theme' => 'stark',
- 'plugin' => 'test_cache',
- ));
- $this->block->save();
- \Drupal::state()->set('block_test.content', NULL);
-
- // Verify cache handling for an empty block.
- $this->verifyRenderCacheHandling();
- }
-
- /**
- * Verifies render cache handling of the block being tested.
- *
- * @see ::testBlockViewBuilderCache()
- */
- protected function verifyRenderCacheHandling() {
- // Force a request via GET so we can get drupal_render() cache working.
- $request_method = \Drupal::request()->server->get('REQUEST_METHOD');
- $this->container->get('request')->setMethod('GET');
-
- // Test that entities with caching disabled do not generate a cache entry.
- $build = $this->getBlockRenderArray();
- $this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == array('tags'), 'The render array element of uncacheable blocks is not cached, but does have cache tags set.');
-
- // Enable block caching.
- $this->setBlockCacheConfig(array(
- 'max_age' => 600,
- ));
-
- // Test that a cache entry is created.
- $build = $this->getBlockRenderArray();
- $cid = drupal_render_cid_create($build);
- drupal_render($build);
- $this->assertTrue($this->container->get('cache.block')->get($cid), 'The block render element has been cached.');
-
- // Re-save the block and check that the cache entry has been deleted.
- $this->block->save();
- $this->assertFalse($this->container->get('cache.block')->get($cid), 'The block render cache entry has been cleared when the block was saved.');
-
- // Rebuild the render array (creating a new cache entry in the process) and
- // delete the block to check the cache entry is deleted.
- unset($build['#printed']);
- drupal_render($build);
- $this->assertTrue($this->container->get('cache.block')->get($cid), 'The block render element has been cached.');
- $this->block->delete();
- $this->assertFalse($this->container->get('cache.block')->get($cid), 'The block render cache entry has been cleared when the block was deleted.');
-
- // Restore the previous request method.
- $this->container->get('request')->setMethod($request_method);
- }
-
- /**
- * Tests block view altering.
- */
- public function testBlockViewBuilderAlter() {
- // Establish baseline.
- $build = $this->getBlockRenderArray();
- $this->assertIdentical(drupal_render($build), 'Llamas > unicorns!');
-
- // Enable the block view alter hook that adds a suffix, for basic testing.
- \Drupal::state()->set('block_test_view_alter_suffix', TRUE);
-
- // Basic: non-empty block.
- $build = $this->getBlockRenderArray();
- $this->assertTrue(isset($build['#suffix']) && $build['#suffix'] === '
Goodbye!', 'A block with content is altered.');
- $this->assertIdentical(drupal_render($build), 'Llamas > unicorns!
Goodbye!');
-
- // Basic: empty block.
- \Drupal::state()->set('block_test.content', NULL);
- $build = $this->getBlockRenderArray();
- $this->assertTrue(isset($build['#suffix']) && $build['#suffix'] === '
Goodbye!', 'A block without content is altered.');
- $this->assertIdentical(drupal_render($build), '
Goodbye!');
-
- // Disable the block view alter hook that adds a suffix, for basic testing.
- \Drupal::state()->set('block_test_view_alter_suffix', FALSE);
-
- // Force a request via GET so we can get drupal_render() cache working.
- $request_method = \Drupal::request()->server->get('REQUEST_METHOD');
- $this->container->get('request')->setMethod('GET');
-
- $default_keys = array('entity_view', 'block', 'test_block', 'en', 'cache_context.theme');
- $default_tags = array('content' => TRUE, 'block_view' => TRUE, 'block' => array('test_block'), 'block_plugin' => array('test_cache'));
-
- // Advanced: cached block, but an alter hook adds an additional cache key.
- $this->setBlockCacheConfig(array(
- 'max_age' => 600,
- ));
- $alter_add_key = $this->randomName();
- \Drupal::state()->set('block_test_view_alter_cache_key', $alter_add_key);
- $expected_keys = array_merge($default_keys, array($alter_add_key));
- $build = $this->getBlockRenderArray();
- $this->assertIdentical($expected_keys, $build['#cache']['keys'], 'An altered cacheable block has the expected cache keys.');
- $cid = drupal_render_cid_create(array('#cache' => array('keys' => $expected_keys)));
- $this->assertIdentical(drupal_render($build), '');
- $cache_entry = $this->container->get('cache.block')->get($cid);
- $this->assertTrue($cache_entry, 'The block render element has been cached with the expected cache ID.');
- $expected_flattened_tags = array('content:1', 'block_view:1', 'block:test_block', 'block_plugin:test_cache');
- $this->assertIdentical($cache_entry->tags, array_combine($expected_flattened_tags, $expected_flattened_tags)); //, 'The block render element has been cached with the expected cache tags.');
- $this->container->get('cache.block')->delete($cid);
-
- // Advanced: cached block, but an alter hook adds an additional cache tag.
- $alter_add_tag = $this->randomName();
- \Drupal::state()->set('block_test_view_alter_cache_tag', $alter_add_tag);
- $expected_tags = NestedArray::mergeDeep($default_tags, array($alter_add_tag => TRUE));
- $build = $this->getBlockRenderArray();
- $this->assertIdentical($expected_tags, $build['#cache']['tags'], 'An altered cacheable block has the expected cache tags.');
- $cid = drupal_render_cid_create(array('#cache' => array('keys' => $expected_keys)));
- $this->assertIdentical(drupal_render($build), '');
- $cache_entry = $this->container->get('cache.block')->get($cid);
- $this->assertTrue($cache_entry, 'The block render element has been cached with the expected cache ID.');
- $expected_flattened_tags = array('content:1', 'block_view:1', 'block:test_block', 'block_plugin:test_cache', $alter_add_tag . ':1');
- $this->assertIdentical($cache_entry->tags, array_combine($expected_flattened_tags, $expected_flattened_tags)); //, 'The block render element has been cached with the expected cache tags.');
- $this->container->get('cache.block')->delete($cid);
-
- // Advanced: cached block, but an alter hook adds a #pre_render callback to
- // alter the eventual content.
- \Drupal::state()->set('block_test_view_alter_append_pre_render_prefix', TRUE);
- $build = $this->getBlockRenderArray();
- $this->assertFalse(isset($build['#prefix']), 'The appended #pre_render callback has not yet run before calling drupal_render().');
- $this->assertIdentical(drupal_render($build), 'Hiya!
');
- $this->assertTrue(isset($build['#prefix']) && $build['#prefix'] === 'Hiya!
', 'A cached block without content is altered.');
-
- // Restore the previous request method.
- $this->container->get('request')->setMethod($request_method);
- }
-
- /**
- * Tests block render cache handling with configurable cache contexts.
- *
- * This is only intended to test that an existing block can be configured with
- * additional contexts, not to test that each context works correctly.
- *
- * @see \Drupal\block\Tests\BlockCacheTest
- */
- public function testBlockViewBuilderCacheContexts() {
- // Force a request via GET so we can get drupal_render() cache working.
- $request_method = \Drupal::request()->server->get('REQUEST_METHOD');
- $this->container->get('request')->setMethod('GET');
-
- // First: no cache context.
- $this->setBlockCacheConfig(array(
- 'max_age' => 600,
- ));
- $build = $this->getBlockRenderArray();
- $cid = drupal_render_cid_create($build);
- drupal_render($build);
- $this->assertTrue($this->container->get('cache.block', $cid), 'The block render element has been cached.');
-
- // Second: the "per URL" cache context.
- $this->setBlockCacheConfig(array(
- 'max_age' => 600,
- 'contexts' => array('cache_context.url'),
- ));
- $old_cid = $cid;
- $build = $this->getBlockRenderArray();
- $cid = drupal_render_cid_create($build);
- drupal_render($build);
- $this->assertTrue($this->container->get('cache.block', $cid), 'The block render element has been cached.');
- $this->assertNotEqual($cid, $old_cid, 'The cache ID has changed.');
-
- // Third: the same block configuration, but a different URL.
- $original_url_cache_context = $this->container->get('cache_context.url');
- $temp_context = new UrlCacheContext(Request::create('/foo'));
- $this->container->set('cache_context.url', $temp_context);
- $old_cid = $cid;
- $build = $this->getBlockRenderArray();
- $cid = drupal_render_cid_create($build);
- drupal_render($build);
- $this->assertTrue($this->container->get('cache.block', $cid), 'The block render element has been cached.');
- $this->assertNotEqual($cid, $old_cid, 'The cache ID has changed.');
- $this->container->set('cache_context.url', $original_url_cache_context);
-
- // Restore the previous request method.
- $this->container->get('request')->setMethod($request_method);
- }
-
- /**
- * Sets the test block's cache configuration.
- *
- * @param array $cache_config
- * The desired cache configuration.
- */
- protected function setBlockCacheConfig(array $cache_config) {
- $block = $this->block->getPlugin();
- $block->setConfigurationValue('cache', $cache_config);
- $this->block->save();
- }
-
- /**
- * Get a fully built render array for a block.
- *
- * @return array
- * The render array.
- */
- protected function getBlockRenderArray() {
- $build = $this->container->get('entity.manager')->getViewBuilder('block')->view($this->block, 'block');
-
- // Mock the build array to not require the theme registry.
- unset($build['#theme']);
-
- return $build;
- }
-
-}
diff --git a/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php b/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php
index ab13127..c43f640 100644
--- a/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php
@@ -177,6 +177,19 @@ protected function testDeleteBlockDisplay() {
}
/**
+ * Tests views block plugin definitions.
+ */
+ public function testViewsBlockPlugins() {
+ // Ensures that the cache setting gets to the block settings.
+ $instance = $this->container->get('plugin.manager.block')->createInstance('views_block:test_view_block2-block_2');
+ $configuration = $instance->getConfiguration();
+ $this->assertEqual($configuration['cache'], DRUPAL_NO_CACHE);
+ $instance = $this->container->get('plugin.manager.block')->createInstance('views_block:test_view_block2-block_3');
+ $configuration = $instance->getConfiguration();
+ $this->assertEqual($configuration['cache'], DRUPAL_CACHE_PER_USER);
+ }
+
+ /**
* Test the block form for a Views block.
*/
public function testViewsBlockForm() {
@@ -270,23 +283,19 @@ public function testBlockRendering() {
public function testBlockContextualLinks() {
$this->drupalLogin($this->drupalCreateUser(array('administer views', 'access contextual links', 'administer blocks')));
$block = $this->drupalPlaceBlock('views_block:test_view_block-block_1');
- $cached_block = $this->drupalPlaceBlock('views_block:test_view_block-block_1', array('cache' => array('max_age' => 3600)));
$this->drupalGet('test-page');
$id = 'block:block=' . $block->id() . ':|views_ui_edit:view=test_view_block:location=block&name=test_view_block&display_id=block_1';
- $cached_id = 'block:block=' . $cached_block->id() . ':|views_ui_edit:view=test_view_block:location=block&name=test_view_block&display_id=block_1';
// @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder()
$this->assertRaw(' $id)) . '>
', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id)));
- $this->assertRaw(' $cached_id)) . '>
', format_string('Contextual link placeholder with id @id exists.', array('@id' => $cached_id)));
// Get server-rendered contextual links.
// @see \Drupal\contextual\Tests\ContextualDynamicContextTest:renderContextualLinks()
- $post = array('ids[0]' => $id, 'ids[1]' => $cached_id);
+ $post = array('ids[0]' => $id);
$response = $this->drupalPost('contextual/render', 'application/json', $post, array('query' => array('destination' => 'test-page')));
$this->assertResponse(200);
$json = Json::decode($response);
$this->assertIdentical($json[$id], '');
- $this->assertIdentical($json[$cached_id], '');
}
}
diff --git a/core/modules/block/tests/Drupal/block/Tests/BlockBaseTest.php b/core/modules/block/tests/Drupal/block/Tests/BlockBaseTest.php
index 8d96c33..f0d04ec 100644
--- a/core/modules/block/tests/Drupal/block/Tests/BlockBaseTest.php
+++ b/core/modules/block/tests/Drupal/block/Tests/BlockBaseTest.php
@@ -12,6 +12,11 @@
use Drupal\Core\Transliteration\PHPTransliteration;
use Drupal\Tests\UnitTestCase;
+// @todo Remove once the constants are replaced with constants on classes.
+if (!defined('DRUPAL_NO_CACHE')) {
+ define('DRUPAL_NO_CACHE', -1);
+}
+
/**
* Tests the base block plugin.
*
diff --git a/core/modules/block/tests/modules/block_test/block_test.module b/core/modules/block/tests/modules/block_test/block_test.module
index a527ae1..1530f2c 100644
--- a/core/modules/block/tests/modules/block_test/block_test.module
+++ b/core/modules/block/tests/modules/block_test/block_test.module
@@ -5,8 +5,6 @@
* Provide test blocks.
*/
-use Drupal\block\BlockPluginInterface;
-
/**
* Implements hook_block_alter().
*/
@@ -15,29 +13,3 @@ function block_test_block_alter(&$block_info) {
$block_info['test_block_instantiation']['category'] = t('Custom category');
}
}
-
-/**
- * Implements hook_block_view_BASE_BLOCK_ID_alter().
- */
-function block_test_block_view_test_cache_alter(array &$build, BlockPluginInterface $block) {
- if (\Drupal::state()->get('block_test_view_alter_suffix') !== NULL) {
- $build['#suffix'] = '
Goodbye!';
- }
- if (\Drupal::state()->get('block_test_view_alter_cache_key') !== NULL) {
- $build['#cache']['keys'][] = \Drupal::state()->get('block_test_view_alter_cache_key');
- }
- if (\Drupal::state()->get('block_test_view_alter_cache_tag') !== NULL) {
- $build['#cache']['tags'][\Drupal::state()->get('block_test_view_alter_cache_tag')] = TRUE;
- }
- if (\Drupal::state()->get('block_test_view_alter_append_pre_render_prefix') !== NULL) {
- $build['#pre_render'][] = 'block_test_pre_render_alter_content';
- }
-}
-
-/**
- * #pre_render callback for a block to alter its content.
- */
-function block_test_pre_render_alter_content($build) {
- $build['#prefix'] = 'Hiya!
';
- return $build;
-}
diff --git a/core/modules/block/tests/modules/block_test/config/block.block.test_block.yml b/core/modules/block/tests/modules/block_test/config/block.block.test_block.yml
index 2b89519..a9eb247 100644
--- a/core/modules/block/tests/modules/block_test/config/block.block.test_block.yml
+++ b/core/modules/block/tests/modules/block_test/config/block.block.test_block.yml
@@ -9,6 +9,7 @@ settings:
label: 'Test HTML block'
module: block_test
label_display: 'hidden'
+ cache: 1
visibility:
path:
visibility: 0
diff --git a/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestCacheBlock.php b/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestCacheBlock.php
index b6508a8..2fa6122 100644
--- a/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestCacheBlock.php
+++ b/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestCacheBlock.php
@@ -21,15 +21,22 @@ class TestCacheBlock extends BlockBase {
/**
* {@inheritdoc}
+ *
+ * Sets a different caching strategy for testing purposes.
*/
- public function build() {
- $content = \Drupal::state()->get('block_test.content');
+ public function defaultConfiguration() {
+ return array(
+ 'cache' => DRUPAL_CACHE_PER_ROLE,
+ );
+ }
- $build = array();
- if (!empty($content)) {
- $build['#markup'] = $content;
- }
- return $build;
+ /**
+ * {@inheritdoc}
+ */
+ public function build() {
+ return array(
+ '#children' => \Drupal::state()->get('block_test.content'),
+ );
}
}
diff --git a/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestXSSTitleBlock.php b/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestXSSTitleBlock.php
index 3146b59..156abf9 100644
--- a/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestXSSTitleBlock.php
+++ b/core/modules/block/tests/modules/block_test/lib/Drupal/block_test/Plugin/Block/TestXSSTitleBlock.php
@@ -16,4 +16,16 @@
* )
*/
class TestXSSTitleBlock extends TestCacheBlock {
+
+ /**
+ * {@inheritdoc}
+ *
+ * Sets a different caching strategy for testing purposes.
+ */
+ public function defaultConfiguration() {
+ return array(
+ 'cache' => DRUPAL_NO_CACHE,
+ );
+ }
+
}
diff --git a/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php b/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
index 6a9cfff..4350e53 100644
--- a/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
+++ b/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php
@@ -65,6 +65,7 @@ public static function create(ContainerInterface $container, array $configuratio
*/
public function defaultConfiguration() {
return array(
+ 'cache' => DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE,
'block_mode' => "all pages",
);
}
@@ -100,7 +101,6 @@ public function blockSubmit($form, &$form_state) {
*/
public function build() {
$current_bid = 0;
-
if ($node = $this->request->get('node')) {
$current_bid = empty($node->book['bid']) ? 0 : $node->book['bid'];
}
@@ -145,21 +145,15 @@ public function build() {
$data = array_shift($tree);
$below = \Drupal::service('book.manager')->bookTreeOutput($data['below']);
if (!empty($below)) {
- return $below;
+ $book_title_link = array('#theme' => 'book_title_link', '#link' => $data['link']);
+ return array(
+ '#title' => drupal_render($book_title_link),
+ $below,
+ );
}
}
}
return array();
}
- /**
- * {@inheritdoc}
- */
- protected function getRequiredCacheContexts() {
- // The "Book navigation" block must be cached per URL and per role: the
- // "active" menu link may differ per URL and different roles may have access
- // to different menu links.
- return array('cache_context.url', 'cache_context.user.roles');
- }
-
}
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php
index 710cc0d..682aeef 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php
@@ -32,10 +32,10 @@ public static function getInfo() {
}
/**
- * Tests entity list builder methods.
+ * Tests entity list controller methods.
*/
function testList() {
- $controller = \Drupal::entityManager()->getListBuilder('config_test');
+ $controller = \Drupal::entityManager()->getListController('config_test');
// Test getStorageController() method.
$this->assertTrue($controller->getStorageController() instanceof EntityStorageControllerInterface, 'EntityStorageController instance in storage.');
@@ -116,7 +116,7 @@ function testList() {
// Test that config entities that do not support status, do not have
// enable/disable operations.
$controller = $this->container->get('entity.manager')
- ->getListBuilder('config_test_no_status');
+ ->getListController('config_test_no_status');
$list = $controller->load();
$entity = $list['default'];
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestListBuilder.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestListBuilder.php
deleted file mode 100644
index 8634b96..0000000
--- a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestListBuilder.php
+++ /dev/null
@@ -1,38 +0,0 @@
-getLabel($entity);
- $row['id'] = $entity->id();
- return $row + parent::buildRow($entity);
- }
-
-}
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestListController.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestListController.php
new file mode 100644
index 0000000..564876a
--- /dev/null
+++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestListController.php
@@ -0,0 +1,36 @@
+getLabel($entity);
+ $row['id'] = $entity->id();
+ return $row + parent::buildRow($entity);
+ }
+
+}
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigQueryTest.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigQueryTest.php
index 53cd76d..c3528f9 100644
--- a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigQueryTest.php
+++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigQueryTest.php
@@ -15,7 +15,7 @@
* label = @Translation("Test configuration for query"),
* controllers = {
* "storage" = "Drupal\config_test\ConfigTestStorageController",
- * "list_builder" = "Drupal\Core\Config\Entity\ConfigEntityListBuilder",
+ * "list" = "Drupal\Core\Config\Entity\ConfigEntityListController",
* "form" = {
* "default" = "Drupal\config_test\ConfigTestFormController"
* }
diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php
index 336afb8..3449b51 100644
--- a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php
+++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php
@@ -18,7 +18,7 @@
* label = @Translation("Test configuration"),
* controllers = {
* "storage" = "Drupal\config_test\ConfigTestStorageController",
- * "list_builder" = "Drupal\config_test\ConfigTestListBuilder",
+ * "list" = "Drupal\config_test\ConfigTestListController",
* "form" = {
* "default" = "Drupal\config_test\ConfigTestFormController",
* "delete" = "Drupal\config_test\Form\ConfigTestDeleteForm"
diff --git a/core/modules/config_translation/config_translation.module b/core/modules/config_translation/config_translation.module
index e500b9d..2204689 100644
--- a/core/modules/config_translation/config_translation.module
+++ b/core/modules/config_translation/config_translation.module
@@ -78,15 +78,15 @@ function config_translation_entity_type_alter(array &$entity_types) {
foreach ($entity_types as $entity_type_id => $entity_type) {
if ($entity_type->isSubclassOf('Drupal\Core\Config\Entity\ConfigEntityInterface')) {
if ($entity_type_id == 'block') {
- $class = 'Drupal\config_translation\Controller\ConfigTranslationBlockListBuilder';
+ $class = 'Drupal\config_translation\Controller\ConfigTranslationBlockListController';
}
elseif ($entity_type_id == 'field_instance_config') {
- $class = 'Drupal\config_translation\Controller\ConfigTranslationFieldInstanceListBuilder';
+ $class = 'Drupal\config_translation\Controller\ConfigTranslationFieldInstanceListController';
// Will be filled in dynamically, see \Drupal\field\Entity\FieldInstanceConfig::linkTemplates().
$entity_type->setLinkTemplate('drupal:config-translation-overview', 'config_translation.item.overview.');
}
else {
- $class = 'Drupal\config_translation\Controller\ConfigTranslationEntityListBuilder';
+ $class = 'Drupal\config_translation\Controller\ConfigTranslationEntityListController';
}
$entity_type->setControllerClass('config_translation_list', $class);
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationBlockListBuilder.php b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationBlockListBuilder.php
deleted file mode 100644
index 90d61bb..0000000
--- a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationBlockListBuilder.php
+++ /dev/null
@@ -1,105 +0,0 @@
-themes = $theme_handler->listInfo();
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('theme_handler')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFilterLabels() {
- $info = parent::getFilterLabels();
-
- $info['placeholder'] = $this->t('Enter block, theme or category');
- $info['description'] = $this->t('Enter a part of the block, theme or category to filter by.');
-
- return $info;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $theme = $entity->get('theme');
- $plugin_definition = $entity->getPlugin()->getPluginDefinition();
-
- $row['label'] = array(
- 'data' => $this->getLabel($entity),
- 'class' => 'table-filter-text-source',
- );
-
- $row['theme'] = array(
- 'data' => String::checkPlain($this->themes[$theme]->info['name']),
- 'class' => 'table-filter-text-source',
- );
-
- $row['category'] = array(
- 'data' => String::checkPlain($plugin_definition['category']),
- 'class' => 'table-filter-text-source',
- );
-
- $row['operations']['data'] = $this->buildOperations($entity);
-
- return $row;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['label'] = $this->t('Block');
- $header['theme'] = $this->t('Theme');
- $header['category'] = $this->t('Category');
- $header['operations'] = $this->t('Operations');
- return $header;
- }
-
- /**
- * {@inheritdoc}
- */
- public function sortRows($a, $b) {
- return $this->sortRowsMultiple($a, $b, array('theme', 'category', 'label'));
- }
-
-}
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationBlockListController.php b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationBlockListController.php
new file mode 100644
index 0000000..c69dcde
--- /dev/null
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationBlockListController.php
@@ -0,0 +1,105 @@
+themes = $theme_handler->listInfo();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('theme_handler')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFilterLabels() {
+ $info = parent::getFilterLabels();
+
+ $info['placeholder'] = $this->t('Enter block, theme or category');
+ $info['description'] = $this->t('Enter a part of the block, theme or category to filter by.');
+
+ return $info;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $theme = $entity->get('theme');
+ $plugin_definition = $entity->getPlugin()->getPluginDefinition();
+
+ $row['label'] = array(
+ 'data' => $this->getLabel($entity),
+ 'class' => 'table-filter-text-source',
+ );
+
+ $row['theme'] = array(
+ 'data' => String::checkPlain($this->themes[$theme]->info['name']),
+ 'class' => 'table-filter-text-source',
+ );
+
+ $row['category'] = array(
+ 'data' => String::checkPlain($plugin_definition['category']),
+ 'class' => 'table-filter-text-source',
+ );
+
+ $row['operations']['data'] = $this->buildOperations($entity);
+
+ return $row;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['label'] = $this->t('Block');
+ $header['theme'] = $this->t('Theme');
+ $header['category'] = $this->t('Category');
+ $header['operations'] = $this->t('Operations');
+ return $header;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sortRows($a, $b) {
+ return $this->sortRowsMultiple($a, $b, array('theme', 'category', 'label'));
+ }
+
+}
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationEntityListBuilder.php b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationEntityListBuilder.php
deleted file mode 100644
index 44f5aad..0000000
--- a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationEntityListBuilder.php
+++ /dev/null
@@ -1,138 +0,0 @@
- $this->t('Enter label'),
- 'description' => $this->t('Enter a part of the label or description to filter by.'),
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function render() {
- $table = parent::render();
- $filter = $this->getFilterLabels();
-
- usort($table['#rows'], array($this, 'sortRows'));
-
- $build['filters'] = array(
- '#type' => 'container',
- '#attributes' => array(
- 'class' => array('table-filter', 'js-show'),
- ),
- );
-
- $build['filters']['text'] = array(
- '#type' => 'search',
- '#title' => $this->t('Search'),
- '#size' => 30,
- '#placeholder' => $filter['placeholder'],
- '#attributes' => array(
- 'class' => array('table-filter-text'),
- 'data-table' => '.config-translation-entity-list',
- 'autocomplete' => 'off',
- 'title' => $filter['description'],
- ),
- );
-
- $build['table'] = $table;
- $build['table']['#attributes']['class'][] = 'config-translation-entity-list';
- $build['#attached']['library'][] = 'system/drupal.system.modules';
-
- return $build;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['label']['data'] = $this->getLabel($entity);
- $row['label']['class'] = 'table-filter-text-source';
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['label'] = $this->t('Label');
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildOperations(EntityInterface $entity) {
- $operations = parent::buildOperations($entity);
- foreach (array_keys($operations['#links']) as $operation) {
- // This is a translation UI for translators. Show the translation
- // operation only.
- if (!($operation == 'translate')) {
- unset($operations['#links'][$operation]);
- }
- }
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function sortRows($a, $b) {
- return $this->sortRowsMultiple($a, $b, array('label'));
- }
-
- /**
- * Sorts an array by multiple criteria.
- *
- * @param array $a
- * First item for comparison.
- * @param array $b
- * Second item for comparison.
- * @param array $keys
- * The array keys to sort on.
- *
- * @return int
- * The comparison result for uasort().
- */
- protected function sortRowsMultiple($a, $b, $keys) {
- $key = array_shift($keys);
- $a_value = (is_array($a) && isset($a[$key]['data'])) ? $a[$key]['data'] : '';
- $b_value = (is_array($b) && isset($b[$key]['data'])) ? $b[$key]['data'] : '';
-
- if ($a_value == $b_value && !empty($keys)) {
- return $this->sortRowsMultiple($a, $b, $keys);
- }
-
- return strnatcasecmp($a_value, $b_value);
- }
-
- /**
- * {@inheritdoc}
- */
- public function setMapperDefinition($mapper_definition) {
- // @todo Why is this method called on all config list controllers?
- return $this;
- }
-
-}
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationEntityListBuilderInterface.php b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationEntityListBuilderInterface.php
deleted file mode 100644
index 08791c8..0000000
--- a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationEntityListBuilderInterface.php
+++ /dev/null
@@ -1,40 +0,0 @@
- $this->t('Enter label'),
+ 'description' => $this->t('Enter a part of the label or description to filter by.'),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ $table = parent::render();
+ $filter = $this->getFilterLabels();
+
+ usort($table['#rows'], array($this, 'sortRows'));
+
+ $build['filters'] = array(
+ '#type' => 'container',
+ '#attributes' => array(
+ 'class' => array('table-filter', 'js-show'),
+ ),
+ );
+
+ $build['filters']['text'] = array(
+ '#type' => 'search',
+ '#title' => $this->t('Search'),
+ '#size' => 30,
+ '#placeholder' => $filter['placeholder'],
+ '#attributes' => array(
+ 'class' => array('table-filter-text'),
+ 'data-table' => '.config-translation-entity-list',
+ 'autocomplete' => 'off',
+ 'title' => $filter['description'],
+ ),
+ );
+
+ $build['table'] = $table;
+ $build['table']['#attributes']['class'][] = 'config-translation-entity-list';
+ $build['#attached']['library'][] = 'system/drupal.system.modules';
+
+ return $build;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['label']['data'] = $this->getLabel($entity);
+ $row['label']['class'] = 'table-filter-text-source';
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['label'] = $this->t('Label');
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildOperations(EntityInterface $entity) {
+ $operations = parent::buildOperations($entity);
+ foreach (array_keys($operations['#links']) as $operation) {
+ // This is a translation UI for translators. Show the translation
+ // operation only.
+ if (!($operation == 'translate')) {
+ unset($operations['#links'][$operation]);
+ }
+ }
+ return $operations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sortRows($a, $b) {
+ return $this->sortRowsMultiple($a, $b, array('label'));
+ }
+
+ /**
+ * Sorts an array by multiple criteria.
+ *
+ * @param array $a
+ * First item for comparison.
+ * @param array $b
+ * Second item for comparison.
+ * @param array $keys
+ * The array keys to sort on.
+ *
+ * @return int
+ * The comparison result for uasort().
+ */
+ protected function sortRowsMultiple($a, $b, $keys) {
+ $key = array_shift($keys);
+ $a_value = (is_array($a) && isset($a[$key]['data'])) ? $a[$key]['data'] : '';
+ $b_value = (is_array($b) && isset($b[$key]['data'])) ? $b[$key]['data'] : '';
+
+ if ($a_value == $b_value && !empty($keys)) {
+ return $this->sortRowsMultiple($a, $b, $keys);
+ }
+
+ return strnatcasecmp($a_value, $b_value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMapperDefinition($mapper_definition) {
+ // @todo Why is this method called on all config list controllers?
+ return $this;
+ }
+
+}
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationEntityListControllerInterface.php b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationEntityListControllerInterface.php
new file mode 100644
index 0000000..f2340b3
--- /dev/null
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationEntityListControllerInterface.php
@@ -0,0 +1,40 @@
+get('entity.manager');
- return new static(
- $entity_type,
- $entity_manager->getStorageController($entity_type->id()),
- $entity_manager
- );
- }
-
- /**
- * Constructs a new ConfigTranslationFieldInstanceListBuilder object.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type definition.
- * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage
- * The entity storage controller class.
- * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
- * The entity manager.
- */
- public function __construct(EntityTypeInterface $entity_type, EntityStorageControllerInterface $storage, EntityManagerInterface $entity_manager) {
- parent::__construct($entity_type, $storage);
- $this->entityManager = $entity_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public function setMapperDefinition($mapper_definition) {
- $this->baseEntityType = $mapper_definition['base_entity_type'];
- $this->baseEntityInfo = $this->entityManager->getDefinition($this->baseEntityType);
- $this->baseEntityBundles = $this->entityManager->getBundleInfo($this->baseEntityType);
- return $this;
- }
-
- /**
- * {@inheritdoc}
- */
- public function load() {
- $entities = array();
- // It is not possible to use the standard load method, because this needs
- // all field instance entities only for the given baseEntityType.
- foreach (Field::fieldInfo()->getInstances($this->baseEntityType) as $fields) {
- $entities = array_merge($entities, array_values($fields));
- }
- return $entities;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFilterLabels() {
- $info = parent::getFilterLabels();
- $bundle = $this->baseEntityInfo->getBundleLabel() ?: $this->t('Bundle');
- $bundle = Unicode::strtolower($bundle);
-
- $info['placeholder'] = $this->t('Enter field or @bundle', array('@bundle' => $bundle));
- $info['description'] = $this->t('Enter a part of the field or @bundle to filter by.', array('@bundle' => $bundle));
-
- return $info;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['label'] = array(
- 'data' => $this->getLabel($entity),
- 'class' => 'table-filter-text-source',
- );
-
- if ($this->displayBundle()) {
- $bundle = $entity->get('bundle');
- $row['bundle'] = array(
- 'data' => String::checkPlain($this->baseEntityBundles[$bundle]['label']),
- 'class' => 'table-filter-text-source',
- );
- }
-
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['label'] = $this->t('Field');
- if ($this->displayBundle()) {
- $header['bundle'] = $this->baseEntityInfo->getBundleLabel() ?: $this->t('Bundle');
- }
- return $header + parent::buildHeader();
- }
-
- /**
- * Controls the visibility of the bundle column on field instance list pages.
- *
- * @return bool
- * Whenever the bundle is displayed or not.
- */
- public function displayBundle() {
- // The bundle key is explicitly defined in the entity definition.
- if ($this->baseEntityInfo->getKey('bundle')) {
- return TRUE;
- }
-
- // There is more than one bundle defined.
- if (count($this->baseEntityBundles) > 1) {
- return TRUE;
- }
-
- // The defined bundle ones not match the entity type name.
- if (!empty($this->baseEntityBundles) && !isset($this->baseEntityBundles[$this->baseEntityType])) {
- return TRUE;
- }
-
- return FALSE;
- }
-
- /**
- * {@inheritdoc}
- */
- public function sortRows($a, $b) {
- return $this->sortRowsMultiple($a, $b, array('bundle', 'label'));
- }
-
-}
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListController.php b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListController.php
new file mode 100644
index 0000000..760b8cb
--- /dev/null
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListController.php
@@ -0,0 +1,179 @@
+get('entity.manager');
+ return new static(
+ $entity_type,
+ $entity_manager->getStorageController($entity_type->id()),
+ $entity_manager
+ );
+ }
+
+ /**
+ * Constructs a new ConfigTranslationFieldInstanceListController object.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type definition.
+ * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage
+ * The entity storage controller class.
+ * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+ * The entity manager.
+ */
+ public function __construct(EntityTypeInterface $entity_type, EntityStorageControllerInterface $storage, EntityManagerInterface $entity_manager) {
+ parent::__construct($entity_type, $storage);
+ $this->entityManager = $entity_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMapperDefinition($mapper_definition) {
+ $this->baseEntityType = $mapper_definition['base_entity_type'];
+ $this->baseEntityInfo = $this->entityManager->getDefinition($this->baseEntityType);
+ $this->baseEntityBundles = $this->entityManager->getBundleInfo($this->baseEntityType);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load() {
+ $entities = array();
+ // It is not possible to use the standard load method, because this needs
+ // all field instance entities only for the given baseEntityType.
+ foreach (Field::fieldInfo()->getInstances($this->baseEntityType) as $fields) {
+ $entities = array_merge($entities, array_values($fields));
+ }
+ return $entities;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFilterLabels() {
+ $info = parent::getFilterLabels();
+ $bundle = $this->baseEntityInfo->getBundleLabel() ?: $this->t('Bundle');
+ $bundle = Unicode::strtolower($bundle);
+
+ $info['placeholder'] = $this->t('Enter field or @bundle', array('@bundle' => $bundle));
+ $info['description'] = $this->t('Enter a part of the field or @bundle to filter by.', array('@bundle' => $bundle));
+
+ return $info;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['label'] = array(
+ 'data' => $this->getLabel($entity),
+ 'class' => 'table-filter-text-source',
+ );
+
+ if ($this->displayBundle()) {
+ $bundle = $entity->get('bundle');
+ $row['bundle'] = array(
+ 'data' => String::checkPlain($this->baseEntityBundles[$bundle]['label']),
+ 'class' => 'table-filter-text-source',
+ );
+ }
+
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['label'] = $this->t('Field');
+ if ($this->displayBundle()) {
+ $header['bundle'] = $this->baseEntityInfo->getBundleLabel() ?: $this->t('Bundle');
+ }
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * Controls the visibility of the bundle column on field instance list pages.
+ *
+ * @return bool
+ * Whenever the bundle is displayed or not.
+ */
+ public function displayBundle() {
+ // The bundle key is explicitly defined in the entity definition.
+ if ($this->baseEntityInfo->getKey('bundle')) {
+ return TRUE;
+ }
+
+ // There is more than one bundle defined.
+ if (count($this->baseEntityBundles) > 1) {
+ return TRUE;
+ }
+
+ // The defined bundle ones not match the entity type name.
+ if (!empty($this->baseEntityBundles) && !isset($this->baseEntityBundles[$this->baseEntityType])) {
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sortRows($a, $b) {
+ return $this->sortRowsMultiple($a, $b, array('bundle', 'label'));
+ }
+
+}
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationMapperList.php b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationMapperList.php
index 23007e9..14f9724 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationMapperList.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationMapperList.php
@@ -120,7 +120,7 @@ public function buildHeader() {
* @return array
* A renderable array of operation links.
*
- * @see \Drupal\Core\Entity\EntityList::buildOperations()
+ * @see \Drupal\Core\Entity\EntityListController::buildOperations()
*/
protected function buildOperations(ConfigMapperInterface $mapper) {
// Retrieve and sort operations.
diff --git a/core/modules/contact/lib/Drupal/contact/CategoryListBuilder.php b/core/modules/contact/lib/Drupal/contact/CategoryListBuilder.php
deleted file mode 100644
index 37169ff..0000000
--- a/core/modules/contact/lib/Drupal/contact/CategoryListBuilder.php
+++ /dev/null
@@ -1,49 +0,0 @@
-getLabel($entity);
- // Special case the personal category.
- if ($entity->id() == 'personal') {
- $row['recipients'] = t('Selected user');
- $row['selected'] = t('No');
- }
- else {
- $row['recipients'] = String::checkPlain(implode(', ', $entity->recipients));
- $default_category = \Drupal::config('contact.settings')->get('default_category');
- $row['selected'] = ($default_category == $entity->id() ? t('Yes') : t('No'));
- }
- return $row + parent::buildRow($entity);
- }
-
-}
diff --git a/core/modules/contact/lib/Drupal/contact/CategoryListController.php b/core/modules/contact/lib/Drupal/contact/CategoryListController.php
new file mode 100644
index 0000000..e68789b
--- /dev/null
+++ b/core/modules/contact/lib/Drupal/contact/CategoryListController.php
@@ -0,0 +1,46 @@
+getLabel($entity);
+ // Special case the personal category.
+ if ($entity->id() == 'personal') {
+ $row['recipients'] = t('Selected user');
+ $row['selected'] = t('No');
+ }
+ else {
+ $row['recipients'] = String::checkPlain(implode(', ', $entity->recipients));
+ $default_category = \Drupal::config('contact.settings')->get('default_category');
+ $row['selected'] = ($default_category == $entity->id() ? t('Yes') : t('No'));
+ }
+ return $row + parent::buildRow($entity);
+ }
+
+}
diff --git a/core/modules/contact/lib/Drupal/contact/Entity/Category.php b/core/modules/contact/lib/Drupal/contact/Entity/Category.php
index 0fc1d7d..a2fe218 100644
--- a/core/modules/contact/lib/Drupal/contact/Entity/Category.php
+++ b/core/modules/contact/lib/Drupal/contact/Entity/Category.php
@@ -19,7 +19,7 @@
* label = @Translation("Contact category"),
* controllers = {
* "access" = "Drupal\contact\CategoryAccessController",
- * "list_builder" = "Drupal\contact\CategoryListBuilder",
+ * "list" = "Drupal\contact\CategoryListController",
* "form" = {
* "add" = "Drupal\contact\CategoryFormController",
* "edit" = "Drupal\contact\CategoryFormController",
diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php
index 4e58485..4b57139 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php
@@ -32,7 +32,7 @@
* label = @Translation("Form mode"),
* controllers = {
* "storage" = "Drupal\entity\EntityDisplayModeStorageController",
- * "list_builder" = "Drupal\entity\EntityFormModeListBuilder",
+ * "list" = "Drupal\entity\EntityFormModeListController",
* "form" = {
* "add" = "Drupal\entity\Form\EntityFormModeAddForm",
* "edit" = "Drupal\entity\Form\EntityDisplayModeEditForm",
diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php
index df31790..2d98442 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php
@@ -32,7 +32,7 @@
* id = "view_mode",
* label = @Translation("View mode"),
* controllers = {
- * "list_builder" = "Drupal\entity\EntityDisplayModeListBuilder",
+ * "list" = "Drupal\entity\EntityDisplayModeListController",
* "form" = {
* "add" = "Drupal\entity\Form\EntityDisplayModeAddForm",
* "edit" = "Drupal\entity\Form\EntityDisplayModeEditForm",
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayModeListBuilder.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayModeListBuilder.php
deleted file mode 100644
index 67f4a2d..0000000
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayModeListBuilder.php
+++ /dev/null
@@ -1,148 +0,0 @@
-entityTypes = $entity_types;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- $entity_manager = $container->get('entity.manager');
- return new static(
- $entity_type,
- $entity_manager->getStorageController($entity_type->id()),
- $entity_manager->getDefinitions()
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['label'] = t('Label');
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['label'] = $this->getLabel($entity);
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function load() {
- $entities = array();
- foreach (parent::load() as $entity) {
- $entities[$entity->getTargetType()][] = $entity;
- }
- return $entities;
- }
-
- /**
- * {@inheritdoc}
- */
- public function render() {
- $build = array();
- foreach ($this->load() as $entity_type => $entities) {
- if (!isset($this->entityTypes[$entity_type])) {
- continue;
- }
-
- // Filter entities
- if ($this->entityTypes[$entity_type]->isFieldable() && !$this->isValidEntity($entity_type)) {
- continue;
- }
-
- $table = array(
- '#prefix' => '' . $this->entityTypes[$entity_type]->getLabel() . '
',
- '#type' => 'table',
- '#header' => $this->buildHeader(),
- '#rows' => array(),
- );
- foreach ($entities as $entity) {
- if ($row = $this->buildRow($entity)) {
- $table['#rows'][$entity->id()] = $row;
- }
- }
-
- // Move content at the top.
- if ($entity_type == 'node') {
- $table['#weight'] = -10;
- }
-
- $short_type = str_replace('_mode', '', $this->entityTypeId);
- $table['#rows']['_add_new'][] = array(
- 'data' => array(
- '#type' => 'link',
- '#href' => "admin/structure/display-modes/$short_type/add/$entity_type",
- '#title' => t('Add new %label @entity-type', array('%label' => $this->entityTypes[$entity_type]->getLabel(), '@entity-type' => $this->entityType->getLowercaseLabel())),
- '#options' => array(
- 'html' => TRUE,
- ),
- ),
- 'colspan' => count($table['#header']),
- );
- $build[$entity_type] = $table;
- }
- return $build;
- }
-
- /**
- * Filters entities based on their controllers.
- *
- * @param $entity_type
- * The entity type of the entity that needs to be validated.
- *
- * @return bool
- * TRUE if the entity has the correct controller, FALSE if the entity
- * doesn't has the correct controller.
- */
- protected function isValidEntity($entity_type) {
- return $this->entityTypes[$entity_type]->hasViewBuilderClass();
- }
-
-}
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayModeListController.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayModeListController.php
new file mode 100644
index 0000000..3e244b3
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayModeListController.php
@@ -0,0 +1,146 @@
+entityTypes = $entity_types;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ $entity_manager = $container->get('entity.manager');
+ return new static(
+ $entity_type,
+ $entity_manager->getStorageController($entity_type->id()),
+ $entity_manager->getDefinitions()
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['label'] = t('Label');
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['label'] = $this->getLabel($entity);
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load() {
+ $entities = array();
+ foreach (parent::load() as $entity) {
+ $entities[$entity->getTargetType()][] = $entity;
+ }
+ return $entities;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ $build = array();
+ foreach ($this->load() as $entity_type => $entities) {
+ if (!isset($this->entityTypes[$entity_type])) {
+ continue;
+ }
+
+ // Filter entities
+ if ($this->entityTypes[$entity_type]->isFieldable() && !$this->isValidEntity($entity_type)) {
+ continue;
+ }
+
+ $table = array(
+ '#prefix' => '' . $this->entityTypes[$entity_type]->getLabel() . '
',
+ '#type' => 'table',
+ '#header' => $this->buildHeader(),
+ '#rows' => array(),
+ );
+ foreach ($entities as $entity) {
+ if ($row = $this->buildRow($entity)) {
+ $table['#rows'][$entity->id()] = $row;
+ }
+ }
+
+ // Move content at the top.
+ if ($entity_type == 'node') {
+ $table['#weight'] = -10;
+ }
+
+ $short_type = str_replace('_mode', '', $this->entityTypeId);
+ $table['#rows']['_add_new'][] = array(
+ 'data' => array(
+ '#type' => 'link',
+ '#href' => "admin/structure/display-modes/$short_type/add/$entity_type",
+ '#title' => t('Add new %label @entity-type', array('%label' => $this->entityTypes[$entity_type]->getLabel(), '@entity-type' => $this->entityType->getLowercaseLabel())),
+ '#options' => array(
+ 'html' => TRUE,
+ ),
+ ),
+ 'colspan' => count($table['#header']),
+ );
+ $build[$entity_type] = $table;
+ }
+ return $build;
+ }
+
+ /**
+ * Filters entities based on their controllers.
+ *
+ * @param $entity_type
+ * The entity type of the entity that needs to be validated.
+ *
+ * @return bool
+ * TRUE if the entity has the correct controller, FALSE if the entity
+ * doesn't has the correct controller.
+ */
+ protected function isValidEntity($entity_type) {
+ return $this->entityTypes[$entity_type]->hasViewBuilderClass();
+ }
+
+}
diff --git a/core/modules/entity/lib/Drupal/entity/EntityFormModeListBuilder.php b/core/modules/entity/lib/Drupal/entity/EntityFormModeListBuilder.php
deleted file mode 100644
index 7c556ab..0000000
--- a/core/modules/entity/lib/Drupal/entity/EntityFormModeListBuilder.php
+++ /dev/null
@@ -1,30 +0,0 @@
-entityTypes[$entity_type]->hasFormClasses();
- }
-
-}
diff --git a/core/modules/entity/lib/Drupal/entity/EntityFormModeListController.php b/core/modules/entity/lib/Drupal/entity/EntityFormModeListController.php
new file mode 100644
index 0000000..04bc923
--- /dev/null
+++ b/core/modules/entity/lib/Drupal/entity/EntityFormModeListController.php
@@ -0,0 +1,28 @@
+entityTypes[$entity_type]->hasFormClasses();
+ }
+
+}
diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module
index 5e218f2..a08593a 100644
--- a/core/modules/field_ui/field_ui.module
+++ b/core/modules/field_ui/field_ui.module
@@ -121,7 +121,7 @@ function field_ui_element_info() {
function field_ui_entity_type_build(array &$entity_types) {
/** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
$entity_types['field_instance_config']->setFormClass('delete', 'Drupal\field_ui\Form\FieldInstanceConfigDeleteForm');
- $entity_types['field_config']->setListBuilderClass('Drupal\field_ui\FieldConfigListBuilder');
+ $entity_types['field_config']->setListClass('Drupal\field_ui\FieldConfigListController');
foreach ($entity_types as $entity_type) {
if ($bundle = $entity_type->getBundleOf()) {
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldConfigListBuilder.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldConfigListBuilder.php
deleted file mode 100644
index d6dfa49..0000000
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldConfigListBuilder.php
+++ /dev/null
@@ -1,124 +0,0 @@
-getStorageController($entity_type->id()));
-
- $this->entityManager = $entity_manager;
- $this->bundles = entity_get_bundles();
- $this->fieldTypeManager = $field_type_manager;
- $this->fieldTypes = $this->fieldTypeManager->getConfigurableDefinitions();
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager'),
- $container->get('plugin.manager.field.field_type')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['id'] = t('Field name');
- $header['type'] = array(
- 'data' => t('Field type'),
- 'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
- );
- $header['usage'] = t('Used in');
- return $header;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $field) {
- if ($field->locked) {
- $row['class'] = array('menu-disabled');
- $row['data']['id'] = t('@field_name (Locked)', array('@field_name' => $field->name));
- }
- else {
- $row['data']['id'] = $field->name;
- }
-
- $field_type = $this->fieldTypes[$field->type];
- $row['data']['type'] = t('@type (module: @module)', array('@type' => $field_type['label'], '@module' => $field_type['provider']));
-
- $usage = array();
- foreach ($field->getBundles() as $bundle) {
- if ($route_info = FieldUI::getOverviewRouteInfo($field->entity_type, $bundle)) {
- $usage[] = \Drupal::l($this->bundles[$field->entity_type][$bundle]['label'], $route_info['route_name'], $route_info['route_parameters'], $route_info['options']);
- }
- else {
- $usage[] = $this->bundles[$field->entity_type][$bundle]['label'];
- }
- }
- $row['data']['usage'] = implode(', ', $usage);
- return $row;
- }
-
-}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldConfigListController.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldConfigListController.php
new file mode 100644
index 0000000..2b473ae
--- /dev/null
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldConfigListController.php
@@ -0,0 +1,121 @@
+getStorageController($entity_type->id()));
+
+ $this->entityManager = $entity_manager;
+ $this->bundles = entity_get_bundles();
+ $this->fieldTypeManager = $field_type_manager;
+ $this->fieldTypes = $this->fieldTypeManager->getConfigurableDefinitions();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager'),
+ $container->get('plugin.manager.field.field_type')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['id'] = t('Field name');
+ $header['type'] = array(
+ 'data' => t('Field type'),
+ 'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
+ );
+ $header['usage'] = t('Used in');
+ return $header;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $field) {
+ if ($field->locked) {
+ $row['class'] = array('menu-disabled');
+ $row['data']['id'] = t('@field_name (Locked)', array('@field_name' => $field->name));
+ }
+ else {
+ $row['data']['id'] = $field->name;
+ }
+
+ $field_type = $this->fieldTypes[$field->type];
+ $row['data']['type'] = t('@type (module: @module)', array('@type' => $field_type['label'], '@module' => $field_type['provider']));
+
+ $usage = array();
+ foreach ($field->getBundles() as $bundle) {
+ if ($route_info = FieldUI::getOverviewRouteInfo($field->entity_type, $bundle)) {
+ $usage[] = \Drupal::l($this->bundles[$field->entity_type][$bundle]['label'], $route_info['route_name'], $route_info['route_parameters'], $route_info['options']);
+ }
+ else {
+ $usage[] = $this->bundles[$field->entity_type][$bundle]['label'];
+ }
+ }
+ $row['data']['usage'] = implode(', ', $usage);
+ return $row;
+ }
+
+}
diff --git a/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php b/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php
index 8e0aadd..cf3bd07 100644
--- a/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php
+++ b/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php
@@ -27,7 +27,7 @@
* "edit" = "Drupal\filter\FilterFormatEditFormController",
* "disable" = "Drupal\filter\Form\FilterDisableForm"
* },
- * "list_builder" = "Drupal\filter\FilterFormatListBuilder",
+ * "list" = "Drupal\filter\FilterFormatListController",
* "access" = "Drupal\filter\FilterFormatAccessController",
* },
* config_prefix = "format",
diff --git a/core/modules/filter/lib/Drupal/filter/FilterFormatListBuilder.php b/core/modules/filter/lib/Drupal/filter/FilterFormatListBuilder.php
deleted file mode 100644
index 7ba51af..0000000
--- a/core/modules/filter/lib/Drupal/filter/FilterFormatListBuilder.php
+++ /dev/null
@@ -1,154 +0,0 @@
-configFactory = $config_factory;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('config.factory')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFormId() {
- return 'filter_admin_overview';
- }
-
- /**
- * {@inheritdoc}
- */
- public function load() {
- // Only list enabled filters.
- return array_filter(parent::load(), function ($entity) {
- return $entity->status();
- });
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['label'] = t('Name');
- $header['roles'] = t('Roles');
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- // Check whether this is the fallback text format. This format is available
- // to all roles and cannot be disabled via the admin interface.
- if ($entity->isFallbackFormat()) {
- $row['label'] = String::placeholder($entity->label());
-
- $fallback_choice = $this->configFactory->get('filter.settings')->get('always_show_fallback_choice');
- if ($fallback_choice) {
- $roles_markup = String::placeholder(t('All roles may use this format'));
- }
- else {
- $roles_markup = String::placeholder(t('This format is shown when no other formats are available'));
- }
- }
- else {
- $row['label'] = $this->getLabel($entity);
- $roles = array_map('\Drupal\Component\Utility\String::checkPlain', filter_get_roles_by_format($entity));
- $roles_markup = $roles ? implode(', ', $roles) : t('No roles may use this format');
- }
-
- $row['roles'] = !empty($this->weightKey) ? array('#markup' => $roles_markup) : $roles_markup;
-
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
-
- if (isset($operations['edit'])) {
- $operations['edit']['title'] = t('Configure');
- }
-
- // The fallback format may not be disabled.
- if ($entity->isFallbackFormat()) {
- unset($operations['disable']);
- }
-
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildForm(array $form, array &$form_state) {
- $form = parent::buildForm($form, $form_state);
- $form['actions']['submit']['#value'] = t('Save changes');
- return $form;
- }
- /**
- * {@inheritdoc}
- */
- public function submitForm(array &$form, array &$form_state) {
- parent::submitForm($form, $form_state);
-
- filter_formats_reset();
- drupal_set_message(t('The text format ordering has been saved.'));
- }
-
-}
diff --git a/core/modules/filter/lib/Drupal/filter/FilterFormatListController.php b/core/modules/filter/lib/Drupal/filter/FilterFormatListController.php
new file mode 100644
index 0000000..e64dce8
--- /dev/null
+++ b/core/modules/filter/lib/Drupal/filter/FilterFormatListController.php
@@ -0,0 +1,153 @@
+configFactory = $config_factory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('config.factory')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'filter_admin_overview';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load() {
+ // Only list enabled filters.
+ return array_filter(parent::load(), function ($entity) {
+ return $entity->status();
+ });
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['label'] = t('Name');
+ $header['roles'] = t('Roles');
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ // Check whether this is the fallback text format. This format is available
+ // to all roles and cannot be disabled via the admin interface.
+ if ($entity->isFallbackFormat()) {
+ $row['label'] = String::placeholder($entity->label());
+
+ $fallback_choice = $this->configFactory->get('filter.settings')->get('always_show_fallback_choice');
+ if ($fallback_choice) {
+ $roles_markup = String::placeholder(t('All roles may use this format'));
+ }
+ else {
+ $roles_markup = String::placeholder(t('This format is shown when no other formats are available'));
+ }
+ }
+ else {
+ $row['label'] = $this->getLabel($entity);
+ $roles = array_map('\Drupal\Component\Utility\String::checkPlain', filter_get_roles_by_format($entity));
+ $roles_markup = $roles ? implode(', ', $roles) : t('No roles may use this format');
+ }
+
+ $row['roles'] = !empty($this->weightKey) ? array('#markup' => $roles_markup) : $roles_markup;
+
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+
+ if (isset($operations['edit'])) {
+ $operations['edit']['title'] = t('Configure');
+ }
+
+ // The fallback format may not be disabled.
+ if ($entity->isFallbackFormat()) {
+ unset($operations['disable']);
+ }
+
+ return $operations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state) {
+ $form = parent::buildForm($form, $form_state);
+ $form['actions']['submit']['#value'] = t('Save changes');
+ return $form;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ parent::submitForm($form, $form_state);
+
+ filter_formats_reset();
+ drupal_set_message(t('The text format ordering has been saved.'));
+ }
+
+}
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index c0e8d3a..959a700 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -539,6 +539,23 @@ function forum_form_node_form_alter(&$form, &$form_state, $form_id) {
}
/**
+ * Render API callback: Lists nodes based on the element's #query property.
+ *
+ * This function can be used as a #pre_render callback.
+ *
+ * @see \Drupal\forum\Plugin\block\block\NewTopicsBlock::build()
+ * @see \Drupal\forum\Plugin\block\block\ActiveTopicsBlock::build()
+ */
+function forum_block_view_pre_render($elements) {
+ $result = $elements['#query']->execute();
+ if ($node_title_list = node_title_list($result)) {
+ $elements['forum_list'] = $node_title_list;
+ $elements['forum_more'] = array('#theme' => 'more_link', '#url' => 'forum', '#title' => t('Read the latest forum topics.'));
+ }
+ return $elements;
+}
+
+/**
* Implements hook_preprocess_HOOK() for block templates.
*/
function forum_preprocess_block(&$variables) {
diff --git a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ActiveTopicsBlock.php b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ActiveTopicsBlock.php
index 133529a..d83f736 100644
--- a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ActiveTopicsBlock.php
+++ b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ActiveTopicsBlock.php
@@ -21,13 +21,17 @@ class ActiveTopicsBlock extends ForumBlockBase {
/**
* {@inheritdoc}
*/
- protected function buildForumQuery() {
- return db_select('forum_index', 'f')
+ public function build() {
+ $query = db_select('forum_index', 'f')
->fields('f')
->addTag('node_access')
->addMetaData('base_table', 'forum_index')
->orderBy('f.last_comment_timestamp', 'DESC')
->range(0, $this->configuration['block_count']);
+
+ return array(
+ drupal_render_cache_by_query($query, 'forum_block_view'),
+ );
}
}
diff --git a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php
index 6b760a9..f1c2f4e 100644
--- a/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php
+++ b/core/modules/forum/lib/Drupal/forum/Plugin/Block/ForumBlockBase.php
@@ -9,7 +9,6 @@
use Drupal\block\BlockBase;
use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\Cache\Cache;
/**
* Provides a base class for Forum blocks.
@@ -19,32 +18,9 @@
/**
* {@inheritdoc}
*/
- public function build() {
- $result = $this->buildForumQuery()->execute();
- if ($node_title_list = node_title_list($result)) {
- $elements['forum_list'] = $node_title_list;
- $elements['forum_more'] = array(
- '#theme' => 'more_link',
- '#url' => 'forum',
- '#title' => t('Read the latest forum topics.')
- );
- }
- return $elements;
- }
-
- /**
- * Builds the select query to use for this forum block.
- *
- * @return \Drupal\Core\Database\Query\Select
- * A Select object.
- */
- abstract protected function buildForumQuery();
-
- /**
- * {@inheritdoc}
- */
public function defaultConfiguration() {
return array(
+ 'cache' => DRUPAL_CACHE_CUSTOM,
'properties' => array(
'administrative' => TRUE,
),
@@ -80,11 +56,4 @@ public function blockSubmit($form, &$form_state) {
$this->configuration['block_count'] = $form_state['values']['block_count'];
}
- /**
- * {@inheritdoc}
- */
- public function getCacheKeys() {
- return array_merge(parent::getCacheKeys(), Cache::keyFromQuery($this->buildForumQuery()));
- }
-
}
diff --git a/core/modules/forum/lib/Drupal/forum/Plugin/Block/NewTopicsBlock.php b/core/modules/forum/lib/Drupal/forum/Plugin/Block/NewTopicsBlock.php
index 635dab4..8b75a83 100644
--- a/core/modules/forum/lib/Drupal/forum/Plugin/Block/NewTopicsBlock.php
+++ b/core/modules/forum/lib/Drupal/forum/Plugin/Block/NewTopicsBlock.php
@@ -21,12 +21,17 @@ class NewTopicsBlock extends ForumBlockBase {
/**
* {@inheritdoc}
*/
- protected function buildForumQuery() {
- return db_select('forum_index', 'f')
+ public function build() {
+ $query = db_select('forum_index', 'f')
->fields('f')
->addTag('node_access')
->addMetaData('base_table', 'forum_index')
->orderBy('f.created', 'DESC')
->range(0, $this->configuration['block_count']);
+
+ return array(
+ drupal_render_cache_by_query($query, 'forum_block_view'),
+ );
}
+
}
diff --git a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
index 55f19a6..2aef8fc 100644
--- a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
+++ b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
@@ -30,7 +30,7 @@
* "delete" = "Drupal\image\Form\ImageStyleDeleteForm",
* "flush" = "Drupal\image\Form\ImageStyleFlushForm"
* },
- * "list_builder" = "Drupal\image\ImageStyleListBuilder",
+ * "list" = "Drupal\image\ImageStyleListController",
* },
* admin_permission = "administer image styles",
* config_prefix = "style",
diff --git a/core/modules/image/lib/Drupal/image/ImageStyleListBuilder.php b/core/modules/image/lib/Drupal/image/ImageStyleListBuilder.php
deleted file mode 100644
index e6eac9e..0000000
--- a/core/modules/image/lib/Drupal/image/ImageStyleListBuilder.php
+++ /dev/null
@@ -1,97 +0,0 @@
-urlGenerator = $url_generator;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('url_generator'),
- $container->get('string_translation')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['label'] = $this->t('Style name');
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['label'] = $this->getLabel($entity);
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $flush = array(
- 'title' => t('Flush'),
- 'weight' => 200,
- ) + $entity->urlInfo('flush-form');
-
- return parent::getOperations($entity) + array('flush' => $flush);
- }
-
- /**
- * {@inheritdoc}
- */
- public function render() {
- $build = parent::render();
- $build['#empty'] = $this->t('There are currently no styles. Add a new one.', array(
- '!url' => $this->urlGenerator->generateFromPath('admin/config/media/image-styles/add'),
- ));
- return $build;
- }
-
-}
diff --git a/core/modules/image/lib/Drupal/image/ImageStyleListController.php b/core/modules/image/lib/Drupal/image/ImageStyleListController.php
new file mode 100644
index 0000000..8d9de4d
--- /dev/null
+++ b/core/modules/image/lib/Drupal/image/ImageStyleListController.php
@@ -0,0 +1,97 @@
+urlGenerator = $url_generator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('url_generator'),
+ $container->get('string_translation')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['label'] = $this->t('Style name');
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['label'] = $this->getLabel($entity);
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $flush = array(
+ 'title' => t('Flush'),
+ 'weight' => 200,
+ ) + $entity->urlInfo('flush-form');
+
+ return parent::getOperations($entity) + array('flush' => $flush);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ $build = parent::render();
+ $build['#empty'] = $this->t('There are currently no styles. Add a new one.', array(
+ '!url' => $this->urlGenerator->generateFromPath('admin/config/media/image-styles/add'),
+ ));
+ return $build;
+ }
+
+}
diff --git a/core/modules/language/lib/Drupal/language/Entity/Language.php b/core/modules/language/lib/Drupal/language/Entity/Language.php
index 244607f..e168aa5 100644
--- a/core/modules/language/lib/Drupal/language/Entity/Language.php
+++ b/core/modules/language/lib/Drupal/language/Entity/Language.php
@@ -19,7 +19,7 @@
* id = "language_entity",
* label = @Translation("Language"),
* controllers = {
- * "list_builder" = "Drupal\language\LanguageListBuilder",
+ * "list" = "Drupal\language\LanguageListController",
* "access" = "Drupal\language\LanguageAccessController",
* "form" = {
* "add" = "Drupal\language\Form\LanguageAddForm",
diff --git a/core/modules/language/lib/Drupal/language/LanguageListBuilder.php b/core/modules/language/lib/Drupal/language/LanguageListBuilder.php
deleted file mode 100644
index 99fb967..0000000
--- a/core/modules/language/lib/Drupal/language/LanguageListBuilder.php
+++ /dev/null
@@ -1,100 +0,0 @@
-storage->loadByProperties(array('locked' => FALSE));
-
- // Sort the entities using the entity class's sort() method.
- // See \Drupal\Core\Config\Entity\ConfigEntityBase::sort().
- uasort($entities, array($this->entityType->getClass(), 'sort'));
- return $entities;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFormId() {
- return 'language_admin_overview_form';
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
- $default = language_default();
-
- // Deleting the site default language is not allowed.
- if ($entity->id() == $default->id) {
- unset($operations['delete']);
- }
-
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['label'] = t('Name');
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['label'] = $this->getLabel($entity);
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildForm(array $form, array &$form_state) {
- $form = parent::buildForm($form, $form_state);
- $form[$this->entitiesKey]['#languages'] = $this->entities;
- $form['actions']['submit']['#value'] = t('Save configuration');
- return $form;
- }
-
- /**
- * {@inheritdoc}
- */
- public function submitForm(array &$form, array &$form_state) {
- parent::submitForm($form, $form_state);
-
- $language_manager = \Drupal::languageManager();
- $language_manager->reset();
- if ($language_manager instanceof ConfigurableLanguageManagerInterface) {
- $language_manager->updateLockedLanguageWeights();
- }
-
- drupal_set_message(t('Configuration saved.'));
- }
-
-}
diff --git a/core/modules/language/lib/Drupal/language/LanguageListController.php b/core/modules/language/lib/Drupal/language/LanguageListController.php
new file mode 100644
index 0000000..da1454f
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/LanguageListController.php
@@ -0,0 +1,97 @@
+storage->loadByProperties(array('locked' => FALSE));
+
+ // Sort the entities using the entity class's sort() method.
+ // See \Drupal\Core\Config\Entity\ConfigEntityBase::sort().
+ uasort($entities, array($this->entityType->getClass(), 'sort'));
+ return $entities;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'language_admin_overview_form';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+ $default = language_default();
+
+ // Deleting the site default language is not allowed.
+ if ($entity->id() == $default->id) {
+ unset($operations['delete']);
+ }
+
+ return $operations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['label'] = t('Name');
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['label'] = $this->getLabel($entity);
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state) {
+ $form = parent::buildForm($form, $form_state);
+ $form[$this->entitiesKey]['#languages'] = $this->entities;
+ $form['actions']['submit']['#value'] = t('Save configuration');
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ parent::submitForm($form, $form_state);
+
+ $language_manager = \Drupal::languageManager();
+ $language_manager->reset();
+ if ($language_manager instanceof ConfigurableLanguageManagerInterface) {
+ $language_manager->updateLockedLanguageWeights();
+ }
+
+ drupal_set_message(t('Configuration saved.'));
+ }
+
+}
diff --git a/core/modules/language/lib/Drupal/language/Plugin/Derivative/LanguageBlock.php b/core/modules/language/lib/Drupal/language/Plugin/Derivative/LanguageBlock.php
index b673d66..88c0736 100644
--- a/core/modules/language/lib/Drupal/language/Plugin/Derivative/LanguageBlock.php
+++ b/core/modules/language/lib/Drupal/language/Plugin/Derivative/LanguageBlock.php
@@ -27,6 +27,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
foreach ($configurable_types as $type) {
$this->derivatives[$type] = $base_plugin_definition;
$this->derivatives[$type]['admin_label'] = t('Language switcher (!type)', array('!type' => $info[$type]['name']));
+ $this->derivatives[$type]['cache'] = DRUPAL_NO_CACHE;
}
// If there is just one configurable type then change the title of the
// block.
diff --git a/core/modules/locale/lib/Drupal/locale/Form/ImportForm.php b/core/modules/locale/lib/Drupal/locale/Form/ImportForm.php
new file mode 100644
index 0000000..32afb37
--- /dev/null
+++ b/core/modules/locale/lib/Drupal/locale/Form/ImportForm.php
@@ -0,0 +1,191 @@
+get('module_handler'),
+ $container->get('language_manager')
+ );
+ }
+ /**
+ * Constructs an ImportForm.
+ *
+ * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+ */
+ public function __construct(ModuleHandlerInterface $module_handler, LanguageManager $language_manager) {
+ $this->moduleHandler = $module_handler;
+ $this->languageManager = $language_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormID() {
+ return 'locale_translate_import_form';
+ }
+
+ /**
+ * Form constructor for the translation import screen.
+ *
+ * @ingroup forms
+ */
+ public function buildForm(array $form, array &$form_state) {
+ $this->languageManager->reset();
+ $languages = $this->languageManager->getLanguages();
+
+ // Initialize a language list to the ones available, including English if we
+ // are to translate Drupal to English as well.
+ $existing_languages = array();
+ foreach ($languages as $langcode => $language) {
+ if ($langcode != 'en' || locale_translate_english()) {
+ $existing_languages[$langcode] = $language->name;
+ }
+ }
+
+ // If we have no languages available, present the list of predefined
+ // languages only. If we do have already added languages, set up two option
+ // groups with the list of existing and then predefined languages.
+ form_load_include($form_state, 'inc', 'language', 'language.admin');
+ if (empty($existing_languages)) {
+ $language_options = language_admin_predefined_list();
+ $default = key($language_options);
+ }
+ else {
+ $default = key($existing_languages);
+ $language_options = array(
+ $this->t('Existing languages') => $existing_languages,
+ $this->t('Languages not yet added') => language_admin_predefined_list()
+ );
+ }
+
+ $validators = array(
+ 'file_validate_extensions' => array('po'),
+ 'file_validate_size' => array(file_upload_max_size()),
+ );
+ $form['file'] = array(
+ '#type' => 'file',
+ '#title' => $this->t('Translation file'),
+ '#description' => array(
+ '#theme' => 'file_upload_help',
+ '#description' => $this->t('A Gettext Portable Object file.'),
+ '#upload_validators' => $validators,
+ ),
+ '#size' => 50,
+ '#upload_validators' => $validators,
+ '#attributes' => array('class' => array('file-import-input')),
+ '#attached' => array(
+ 'js' => array(
+ drupal_get_path('module', 'locale') . '/locale.bulk.js' => array(),
+ ),
+ ),
+ );
+ $form['langcode'] = array(
+ '#type' => 'select',
+ '#title' => $this->t('Language'),
+ '#options' => $language_options,
+ '#default_value' => $default,
+ '#attributes' => array('class' => array('langcode-input')),
+ );
+
+ $form['customized'] = array(
+ '#title' => $this->t('Treat imported strings as custom translations'),
+ '#type' => 'checkbox',
+ );
+ $form['overwrite_options'] = array(
+ '#type' => 'container',
+ '#tree' => TRUE,
+ );
+ $form['overwrite_options']['not_customized'] = array(
+ '#title' => $this->t('Overwrite non-customized translations'),
+ '#type' => 'checkbox',
+ '#states' => array(
+ 'checked' => array(
+ ':input[name="customized"]' => array('checked' => TRUE),
+ ),
+ ),
+ );
+ $form['overwrite_options']['customized'] = array(
+ '#title' => $this->t('Overwrite existing customized translations'),
+ '#type' => 'checkbox',
+ );
+
+ $form['actions'] = array(
+ '#type' => 'actions'
+ );
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => $this->t('Import')
+ );
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ // Ensure we have the file uploaded.
+ if ($file = file_save_upload('file', $form_state, $form['file']['#upload_validators'], 'translations://', 0)) {
+
+ // Add language, if not yet supported.
+ $language = language_load($form_state['values']['langcode']);
+ if (empty($language)) {
+ $language = new Language(array(
+ 'id' => $form_state['values']['langcode']
+ ));
+ $language = language_save($language);
+ drupal_set_message(t('The language %language has been created.', array('%language' => t($language->name))));
+ }
+ $options = array(
+ 'langcode' => $form_state['values']['langcode'],
+ 'overwrite_options' => $form_state['values']['overwrite_options'],
+ 'customized' => $form_state['values']['customized'] ? LOCALE_CUSTOMIZED : LOCALE_NOT_CUSTOMIZED,
+ );
+ $this->moduleHandler->loadInclude('locale', 'bulk.inc');
+ $file = locale_translate_file_attach_properties($file, $options);
+ $batch = locale_translate_batch_build(array($file->uri => $file), $options);
+ batch_set($batch);
+ }
+ else {
+ $this->setFormError('file', $form_state, $this->t('File to import not found.'));
+ $form_state['rebuild'] = TRUE;
+ return;
+ }
+
+ $form_state['redirect_route']['route_name'] = 'locale.translate_page';
+ }
+}
diff --git a/core/modules/locale/lib/Drupal/locale/Form/LocaleForm.php b/core/modules/locale/lib/Drupal/locale/Form/LocaleForm.php
index aaa0bfa..c06a4aa 100644
--- a/core/modules/locale/lib/Drupal/locale/Form/LocaleForm.php
+++ b/core/modules/locale/lib/Drupal/locale/Form/LocaleForm.php
@@ -22,6 +22,16 @@ public function import() {
}
/**
+ * Wraps locale_translate_export_form().
+ *
+ * @todo Remove locale_translate_export_form().
+ */
+ public function export() {
+ module_load_include('bulk.inc', 'locale');
+ return drupal_get_form('locale_translate_export_form');
+ }
+
+ /**
* Wraps locale_translation_status_form().
*
* @todo Remove locale_translation_status_form().
diff --git a/core/modules/locale/locale.bulk.inc b/core/modules/locale/locale.bulk.inc
index 5f72ad8..af27887 100644
--- a/core/modules/locale/locale.bulk.inc
+++ b/core/modules/locale/locale.bulk.inc
@@ -10,96 +10,70 @@
use Drupal\file\FileInterface;
/**
- * Form constructor for the translation import screen.
+ * Form constructor for the Gettext translation files export form.
*
- * @see locale_translate_import_form_submit()
+ * @see locale_translate_export_form_submit()
* @ingroup forms
*
- * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
- * Use \Drupal\locale\Form\LocaleForm::import().
+ * @deprecated Use \Drupal\locale\Form\LocaleForm::export()
*/
-function locale_translate_import_form($form, &$form_state) {
- Drupal::languageManager()->reset();
+function locale_translate_export_form($form, &$form_state) {
$languages = language_list();
-
- // Initialize a language list to the ones available, including English if we
- // are to translate Drupal to English as well.
- $existing_languages = array();
+ $language_options = array();
foreach ($languages as $langcode => $language) {
if ($langcode != 'en' || locale_translate_english()) {
- $existing_languages[$langcode] = $language->name;
+ $language_options[$langcode] = $language->name;
}
}
+ $language_default = language_default();
- // If we have no languages available, present the list of predefined languages
- // only. If we do have already added languages, set up two option groups with
- // the list of existing and then predefined languages.
- form_load_include($form_state, 'inc', 'language', 'language.admin');
- if (empty($existing_languages)) {
- $language_options = language_admin_predefined_list();
- $default = key($language_options);
+ if (empty($language_options)) {
+ $form['langcode'] = array(
+ '#type' => 'value',
+ '#value' => Language::LANGCODE_SYSTEM,
+ );
+ $form['langcode_text'] = array(
+ '#type' => 'item',
+ '#title' => t('Language'),
+ '#markup' => t('No language available. The export will only contain source strings.'),
+ );
}
else {
- $default = key($existing_languages);
- $language_options = array(
- t('Existing languages') => $existing_languages,
- t('Languages not yet added') => language_admin_predefined_list()
+ $form['langcode'] = array(
+ '#type' => 'select',
+ '#title' => t('Language'),
+ '#options' => $language_options,
+ '#default_value' => $language_default->id,
+ '#empty_option' => t('Source text only, no translations'),
+ '#empty_value' => Language::LANGCODE_SYSTEM,
);
- }
-
- $validators = array(
- 'file_validate_extensions' => array('po'),
- 'file_validate_size' => array(file_upload_max_size()),
- );
- $file_description = array(
- '#theme' => 'file_upload_help',
- '#description' => t('A Gettext Portable Object file.'),
- '#upload_validators' => $validators,
- );
-
- $form['file'] = array(
- '#type' => 'file',
- '#title' => t('Translation file'),
- '#description' => drupal_render($file_description),
- '#size' => 50,
- '#upload_validators' => $validators,
- '#attributes' => array('class' => array('file-import-input')),
- '#attached' => array(
- 'js' => array(
- drupal_get_path('module', 'locale') . '/locale.bulk.js' => array(),
+ $form['content_options'] = array(
+ '#type' => 'details',
+ '#title' => t('Export options'),
+ '#collapsed' => TRUE,
+ '#tree' => TRUE,
+ '#states' => array(
+ 'invisible' => array(
+ ':input[name="langcode"]' => array('value' => Language::LANGCODE_SYSTEM),
+ ),
),
- ),
- );
- $form['langcode'] = array(
- '#type' => 'select',
- '#title' => t('Language'),
- '#options' => $language_options,
- '#default_value' => $default,
- '#attributes' => array('class' => array('langcode-input')),
- );
-
- $form['customized'] = array(
- '#title' => t('Treat imported strings as custom translations'),
- '#type' => 'checkbox',
- );
- $form['overwrite_options'] = array(
- '#type' => 'container',
- '#tree' => TRUE,
- );
- $form['overwrite_options']['not_customized'] = array(
- '#title' => t('Overwrite non-customized translations'),
- '#type' => 'checkbox',
- '#states' => array(
- 'checked' => array(
- ':input[name="customized"]' => array('checked' => TRUE),
- ),
- ),
- );
- $form['overwrite_options']['customized'] = array(
- '#title' => t('Overwrite existing customized translations'),
- '#type' => 'checkbox',
- );
-
+ );
+ $form['content_options']['not_customized'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Include non-customized translations'),
+ '#default_value' => TRUE,
+ );
+ $form['content_options']['customized'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Include customized translations'),
+ '#default_value' => TRUE,
+ );
+ $form['content_options']['not_translated'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Include untranslated text'),
+ '#default_value' => TRUE,
+ );
+ }
$form['actions'] = array(
'#type' => 'actions'
);
@@ -111,38 +85,56 @@ function locale_translate_import_form($form, &$form_state) {
}
/**
- * Form submission handler for locale_translate_import_form().
+ * Form submission handler for locale_translate_export_form().
*/
-function locale_translate_import_form_submit($form, &$form_state) {
- // Ensure we have the file uploaded.
- if ($file = file_save_upload('file', $form_state, $form['file']['#upload_validators'], 'translations://', 0)) {
-
- // Add language, if not yet supported.
+function locale_translate_export_form_submit($form, &$form_state) {
+ // If template is required, language code is not given.
+ if ($form_state['values']['langcode'] != Language::LANGCODE_SYSTEM) {
$language = language_load($form_state['values']['langcode']);
- if (empty($language)) {
- $language = new Language(array(
- 'id' => $form_state['values']['langcode']
- ));
- $language = language_save($language);
- drupal_set_message(t('The language %language has been created.', array('%language' => t($language->name))));
- }
- $options = array(
- 'langcode' => $form_state['values']['langcode'],
- 'overwrite_options' => $form_state['values']['overwrite_options'],
- 'customized' => $form_state['values']['customized'] ? LOCALE_CUSTOMIZED : LOCALE_NOT_CUSTOMIZED,
- );
- $file = locale_translate_file_attach_properties($file, $options);
- $batch = locale_translate_batch_build(array($file->uri => $file), $options);
- batch_set($batch);
}
else {
- form_set_error('file', $form_state, t('File to import not found.'));
- $form_state['rebuild'] = TRUE;
- return;
+ $language = NULL;
+ }
+ $content_options = isset($form_state['values']['content_options']) ? $form_state['values']['content_options'] : array();
+ $reader = new PoDatabaseReader();
+ $languageName = '';
+ if ($language != NULL) {
+ $reader->setLangcode($language->id);
+ $reader->setOptions($content_options);
+ $languages = language_list();
+ $languageName = isset($languages[$language->id]) ? $languages[$language->id]->name : '';
+ $filename = $language->id .'.po';
+ }
+ else {
+ // Template required.
+ $filename = 'drupal.pot';
}
- $form_state['redirect_route']['route_name'] = 'locale.translate_page';
- return;
+ $item = $reader->readItem();
+ if (!empty($item)) {
+ $uri = tempnam('temporary://', 'po_');
+ $header = $reader->getHeader();
+ $header->setProjectName(\Drupal::config('system.site')->get('name'));
+ $header->setLanguageName($languageName);
+
+ $writer = new PoStreamWriter;
+ $writer->setUri($uri);
+ $writer->setHeader($header);
+
+ $writer->open();
+ $writer->writeItem($item);
+ $writer->writeItems($reader);
+ $writer->close();
+
+ $response = new BinaryFileResponse($uri);
+ $response->setContentDisposition('attachment', $filename);
+ // @todo remove lines below once converted to new routing system.
+ $response->prepare(\Drupal::request())
+ ->send();
+ }
+ else {
+ drupal_set_message('Nothing to export.');
+ }
}
/**
diff --git a/core/modules/locale/locale.routing.yml b/core/modules/locale/locale.routing.yml
index 6658dad..705d5ea 100644
--- a/core/modules/locale/locale.routing.yml
+++ b/core/modules/locale/locale.routing.yml
@@ -24,7 +24,7 @@ locale.translate_page:
locale.translate_import:
path: '/admin/config/regional/translate/import'
defaults:
- _content: '\Drupal\locale\Form\LocaleForm::import'
+ _form: '\Drupal\locale\Form\ImportForm'
_title: 'Import'
requirements:
_permission: 'translate interface'
diff --git a/core/modules/menu/lib/Drupal/menu/MenuListBuilder.php b/core/modules/menu/lib/Drupal/menu/MenuListBuilder.php
deleted file mode 100644
index 282ce00..0000000
--- a/core/modules/menu/lib/Drupal/menu/MenuListBuilder.php
+++ /dev/null
@@ -1,73 +0,0 @@
- t('Description'),
- 'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
- );
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['title'] = array(
- 'data' => $this->getLabel($entity),
- 'class' => array('menu-label'),
- );
- $row['description'] = filter_xss_admin($entity->description);
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
-
- if (isset($operations['edit'])) {
- $operations['edit']['title'] = t('Edit menu');
- $operations['add'] = array(
- 'title' => t('Add link'),
- 'weight' => 20,
- ) + $entity->urlInfo('add-form');
- }
- if (isset($operations['delete'])) {
- $operations['delete']['title'] = t('Delete menu');
- }
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function render() {
- $build = parent::render();
- $build['#attached']['css'][] = drupal_get_path('module', 'menu') . '/css/menu.admin.css';
- return $build;
- }
-
-}
diff --git a/core/modules/menu/lib/Drupal/menu/MenuListController.php b/core/modules/menu/lib/Drupal/menu/MenuListController.php
new file mode 100644
index 0000000..18a3732
--- /dev/null
+++ b/core/modules/menu/lib/Drupal/menu/MenuListController.php
@@ -0,0 +1,69 @@
+ t('Description'),
+ 'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
+ );
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * Overrides \Drupal\Core\Entity\EntityListController::buildRow().
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['title'] = array(
+ 'data' => $this->getLabel($entity),
+ 'class' => array('menu-label'),
+ );
+ $row['description'] = filter_xss_admin($entity->description);
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+
+ if (isset($operations['edit'])) {
+ $operations['edit']['title'] = t('Edit menu');
+ $operations['add'] = array(
+ 'title' => t('Add link'),
+ 'weight' => 20,
+ ) + $entity->urlInfo('add-form');
+ }
+ if (isset($operations['delete'])) {
+ $operations['delete']['title'] = t('Delete menu');
+ }
+ return $operations;
+ }
+
+ /**
+ * Overrides \Drupal\Core\Entity\EntityListController::render();
+ */
+ public function render() {
+ $build = parent::render();
+ $build['#attached']['css'][] = drupal_get_path('module', 'menu') . '/css/menu.admin.css';
+ return $build;
+ }
+
+}
diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuCacheTagsTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuCacheTagsTest.php
index e8f00a3..c09875c 100644
--- a/core/modules/menu/lib/Drupal/menu/Tests/MenuCacheTagsTest.php
+++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuCacheTagsTest.php
@@ -58,14 +58,7 @@ public function testMenuBlock() {
$this->verifyPageCache($path, 'MISS');
// Verify a cache hit, but also the presence of the correct cache tags.
- $expected_tags = array(
- 'content:1',
- 'block_view:1',
- 'block:' . $block->id(),
- 'block_plugin:system_menu_block__llama',
- 'menu:llama',
- );
- $this->verifyPageCache($path, 'HIT', $expected_tags);
+ $this->verifyPageCache($path, 'HIT', array('content:1', 'menu:llama'));
// Verify that after modifying the menu, there is a cache miss.
@@ -108,7 +101,7 @@ public function testMenuBlock() {
$this->verifyPageCache($path, 'MISS');
// Verify a cache hit.
- $this->verifyPageCache($path, 'HIT', $expected_tags);
+ $this->verifyPageCache($path, 'HIT', array('content:1', 'menu:llama'));
// Verify that after deleting the menu, there is a cache miss.
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index 9f84463..660e1df 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -84,7 +84,7 @@ function menu_entity_type_build(array &$entity_types) {
->setFormClass('add', 'Drupal\menu\MenuFormController')
->setFormClass('edit', 'Drupal\menu\MenuFormController')
->setFormClass('delete', 'Drupal\menu\Form\MenuDeleteForm')
- ->setListBuilderClass('Drupal\menu\MenuListBuilder')
+ ->setListClass('Drupal\menu\MenuListController')
->setLinkTemplate('add-form', 'menu.link_add')
->setLinkTemplate('delete-form', 'menu.delete_menu')
->setLinkTemplate('edit-form', 'menu.menu_edit');
diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php
index da4b174..a80577c 100644
--- a/core/modules/node/lib/Drupal/node/Entity/Node.php
+++ b/core/modules/node/lib/Drupal/node/Entity/Node.php
@@ -31,7 +31,7 @@
* "delete" = "Drupal\node\Form\NodeDeleteForm",
* "edit" = "Drupal\node\NodeFormController"
* },
- * "list_builder" = "Drupal\node\NodeListBuilder",
+ * "list" = "Drupal\node\NodeListController",
* "translation" = "Drupal\node\NodeTranslationController"
* },
* base_table = "node",
diff --git a/core/modules/node/lib/Drupal/node/Entity/NodeType.php b/core/modules/node/lib/Drupal/node/Entity/NodeType.php
index b187c75..021ee7d 100644
--- a/core/modules/node/lib/Drupal/node/Entity/NodeType.php
+++ b/core/modules/node/lib/Drupal/node/Entity/NodeType.php
@@ -26,7 +26,7 @@
* "edit" = "Drupal\node\NodeTypeFormController",
* "delete" = "Drupal\node\Form\NodeTypeDeleteConfirm"
* },
- * "list_builder" = "Drupal\node\NodeTypeListBuilder",
+ * "list" = "Drupal\node\NodeTypeListController",
* },
* admin_permission = "administer content types",
* config_prefix = "type",
diff --git a/core/modules/node/lib/Drupal/node/NodeListBuilder.php b/core/modules/node/lib/Drupal/node/NodeListBuilder.php
deleted file mode 100644
index d80b6b2..0000000
--- a/core/modules/node/lib/Drupal/node/NodeListBuilder.php
+++ /dev/null
@@ -1,137 +0,0 @@
-dateService = $date_service;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('date')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- // Enable language column and filter if multiple languages are enabled.
- $header = array(
- 'title' => $this->t('Title'),
- 'type' => array(
- 'data' => $this->t('Content type'),
- 'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
- ),
- 'author' => array(
- 'data' => $this->t('Author'),
- 'class' => array(RESPONSIVE_PRIORITY_LOW),
- ),
- 'status' => $this->t('Status'),
- 'changed' => array(
- 'data' => $this->t('Updated'),
- 'class' => array(RESPONSIVE_PRIORITY_LOW),
- ),
- );
- if (\Drupal::languageManager()->isMultilingual()) {
- $header['language_name'] = array(
- 'data' => $this->t('Language'),
- 'class' => array(RESPONSIVE_PRIORITY_LOW),
- );
- }
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- /** @var \Drupal\node\NodeInterface $entity */
- $mark = array(
- '#theme' => 'mark',
- '#mark_type' => node_mark($entity->id(), $entity->getChangedTime()),
- );
- $langcode = $entity->language()->id;
- $uri = $entity->urlInfo();
- $row['title']['data'] = array(
- '#type' => 'link',
- '#title' => $entity->label(),
- '#route_name' => $uri['route_name'],
- '#route_parameters' => $uri['route_parameters'],
- '#options' => $uri['options'] + ($langcode != Language::LANGCODE_NOT_SPECIFIED && isset($languages[$langcode]) ? array('language' => $languages[$langcode]) : array()),
- '#suffix' => ' ' . drupal_render($mark),
- );
- $row['type'] = String::checkPlain(node_get_type_label($entity));
- $row['author']['data'] = array(
- '#theme' => 'username',
- '#account' => $entity->getOwner(),
- );
- $row['status'] = $entity->isPublished() ? $this->t('published') : $this->t('not published');
- $row['changed'] = $this->dateService->format($entity->getChangedTime(), 'short');
- $language_manager = \Drupal::languageManager();
- if ($language_manager->isMultilingual()) {
- $row['language_name'] = $language_manager->getLanguageName($langcode);
- }
- $row['operations']['data'] = $this->buildOperations($entity);
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
-
- $destination = drupal_get_destination();
- foreach ($operations as $key => $operation) {
- $operations[$key]['query'] = $destination;
- }
- return $operations;
- }
-
-}
diff --git a/core/modules/node/lib/Drupal/node/NodeListController.php b/core/modules/node/lib/Drupal/node/NodeListController.php
new file mode 100644
index 0000000..4ac1ebb
--- /dev/null
+++ b/core/modules/node/lib/Drupal/node/NodeListController.php
@@ -0,0 +1,136 @@
+dateService = $date_service;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('date')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ // Enable language column and filter if multiple languages are enabled.
+ $header = array(
+ 'title' => $this->t('Title'),
+ 'type' => array(
+ 'data' => $this->t('Content type'),
+ 'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
+ ),
+ 'author' => array(
+ 'data' => $this->t('Author'),
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ ),
+ 'status' => $this->t('Status'),
+ 'changed' => array(
+ 'data' => $this->t('Updated'),
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ ),
+ );
+ if (\Drupal::languageManager()->isMultilingual()) {
+ $header['language_name'] = array(
+ 'data' => $this->t('Language'),
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ );
+ }
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ /** @var \Drupal\node\NodeInterface $entity */
+ $mark = array(
+ '#theme' => 'mark',
+ '#mark_type' => node_mark($entity->id(), $entity->getChangedTime()),
+ );
+ $langcode = $entity->language()->id;
+ $uri = $entity->urlInfo();
+ $row['title']['data'] = array(
+ '#type' => 'link',
+ '#title' => $entity->label(),
+ '#route_name' => $uri['route_name'],
+ '#route_parameters' => $uri['route_parameters'],
+ '#options' => $uri['options'] + ($langcode != Language::LANGCODE_NOT_SPECIFIED && isset($languages[$langcode]) ? array('language' => $languages[$langcode]) : array()),
+ '#suffix' => ' ' . drupal_render($mark),
+ );
+ $row['type'] = String::checkPlain(node_get_type_label($entity));
+ $row['author']['data'] = array(
+ '#theme' => 'username',
+ '#account' => $entity->getOwner(),
+ );
+ $row['status'] = $entity->isPublished() ? $this->t('published') : $this->t('not published');
+ $row['changed'] = $this->dateService->format($entity->getChangedTime(), 'short');
+ $language_manager = \Drupal::languageManager();
+ if ($language_manager->isMultilingual()) {
+ $row['language_name'] = $language_manager->getLanguageName($langcode);
+ }
+ $row['operations']['data'] = $this->buildOperations($entity);
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+
+ $destination = drupal_get_destination();
+ foreach ($operations as $key => $operation) {
+ $operations[$key]['query'] = $destination;
+ }
+ return $operations;
+ }
+
+}
diff --git a/core/modules/node/lib/Drupal/node/NodeTypeListBuilder.php b/core/modules/node/lib/Drupal/node/NodeTypeListBuilder.php
deleted file mode 100644
index 681fff4..0000000
--- a/core/modules/node/lib/Drupal/node/NodeTypeListBuilder.php
+++ /dev/null
@@ -1,107 +0,0 @@
-urlGenerator = $url_generator;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('url_generator')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['title'] = t('Name');
- $header['description'] = array(
- 'data' => t('Description'),
- 'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
- );
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['title'] = array(
- 'data' => $this->getLabel($entity),
- 'class' => array('menu-label'),
- );
- $row['description'] = Xss::filterAdmin($entity->description);
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
- // Place the edit operation after the operations added by field_ui.module
- // which have the weights 15, 20, 25.
- if (isset($operations['edit'])) {
- $operations['edit']['weight'] = 30;
- }
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function render() {
- $build = parent::render();
- $build['#empty'] = t('No content types available. Add content type.', array(
- '@link' => $this->urlGenerator->generateFromPath('admin/structure/types/add'),
- ));
- return $build;
- }
-
-}
diff --git a/core/modules/node/lib/Drupal/node/NodeTypeListController.php b/core/modules/node/lib/Drupal/node/NodeTypeListController.php
new file mode 100644
index 0000000..b1829f6
--- /dev/null
+++ b/core/modules/node/lib/Drupal/node/NodeTypeListController.php
@@ -0,0 +1,105 @@
+urlGenerator = $url_generator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('url_generator')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['title'] = t('Name');
+ $header['description'] = array(
+ 'data' => t('Description'),
+ 'class' => array(RESPONSIVE_PRIORITY_MEDIUM),
+ );
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['title'] = array(
+ 'data' => $this->getLabel($entity),
+ 'class' => array('menu-label'),
+ );
+ $row['description'] = Xss::filterAdmin($entity->description);
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+ // Place the edit operation after the operations added by field_ui.module
+ // which have the weights 15, 20, 25.
+ if (isset($operations['edit'])) {
+ $operations['edit']['weight'] = 30;
+ }
+ return $operations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ $build = parent::render();
+ $build['#empty'] = t('No content types available. Add content type.', array(
+ '@link' => $this->urlGenerator->generateFromPath('admin/structure/types/add'),
+ ));
+ return $build;
+ }
+
+}
diff --git a/core/modules/responsive_image/lib/Drupal/responsive_image/Entity/ResponsiveImageMapping.php b/core/modules/responsive_image/lib/Drupal/responsive_image/Entity/ResponsiveImageMapping.php
index 658ad5d..408e417 100644
--- a/core/modules/responsive_image/lib/Drupal/responsive_image/Entity/ResponsiveImageMapping.php
+++ b/core/modules/responsive_image/lib/Drupal/responsive_image/Entity/ResponsiveImageMapping.php
@@ -17,7 +17,7 @@
* id = "responsive_image_mapping",
* label = @Translation("Responsive image mapping"),
* controllers = {
- * "list_builder" = "Drupal\responsive_image\ResponsiveImageMappingListBuilder",
+ * "list" = "Drupal\responsive_image\ResponsiveImageMappingListController",
* "form" = {
* "edit" = "Drupal\responsive_image\ResponsiveImageMappingFormController",
* "add" = "Drupal\responsive_image\ResponsiveImageMappingFormController",
diff --git a/core/modules/responsive_image/lib/Drupal/responsive_image/ResponsiveImageMappingListBuilder.php b/core/modules/responsive_image/lib/Drupal/responsive_image/ResponsiveImageMappingListBuilder.php
deleted file mode 100644
index 1de736b..0000000
--- a/core/modules/responsive_image/lib/Drupal/responsive_image/ResponsiveImageMappingListBuilder.php
+++ /dev/null
@@ -1,48 +0,0 @@
-getLabel($entity);
- $row['id'] = $entity->id();
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
- $operations['duplicate'] = array(
- 'title' => t('Duplicate'),
- 'weight' => 15,
- ) + $entity->urlInfo('duplicate-form');
- return $operations;
- }
-
-}
diff --git a/core/modules/responsive_image/lib/Drupal/responsive_image/ResponsiveImageMappingListController.php b/core/modules/responsive_image/lib/Drupal/responsive_image/ResponsiveImageMappingListController.php
new file mode 100644
index 0000000..7d392b8
--- /dev/null
+++ b/core/modules/responsive_image/lib/Drupal/responsive_image/ResponsiveImageMappingListController.php
@@ -0,0 +1,48 @@
+getLabel($entity);
+ $row['id'] = $entity->id();
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+ $operations['duplicate'] = array(
+ 'title' => t('Duplicate'),
+ 'weight' => 15,
+ ) + $entity->urlInfo('duplicate-form');
+ return $operations;
+ }
+
+}
diff --git a/core/modules/search/lib/Drupal/search/Entity/SearchPage.php b/core/modules/search/lib/Drupal/search/Entity/SearchPage.php
index 18a1807..ab902b5 100644
--- a/core/modules/search/lib/Drupal/search/Entity/SearchPage.php
+++ b/core/modules/search/lib/Drupal/search/Entity/SearchPage.php
@@ -24,7 +24,7 @@
* controllers = {
* "access" = "Drupal\search\SearchPageAccessController",
* "storage" = "Drupal\Core\Config\Entity\ConfigStorageController",
- * "list_builder" = "Drupal\search\SearchPageListBuilder",
+ * "list" = "Drupal\search\SearchPageListController",
* "form" = {
* "add" = "Drupal\search\Form\SearchPageAddForm",
* "edit" = "Drupal\search\Form\SearchPageEditForm",
diff --git a/core/modules/search/lib/Drupal/search/SearchPageListBuilder.php b/core/modules/search/lib/Drupal/search/SearchPageListBuilder.php
deleted file mode 100644
index e2c61cd..0000000
--- a/core/modules/search/lib/Drupal/search/SearchPageListBuilder.php
+++ /dev/null
@@ -1,343 +0,0 @@
-configFactory = $config_factory;
- $this->searchManager = $search_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('plugin.manager.search'),
- $container->get('config.factory')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFormID() {
- return 'search_admin_settings';
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['label'] = array(
- 'data' => $this->t('Label'),
- );
- $header['url'] = array(
- 'data' => $this->t('URL'),
- 'class' => array(RESPONSIVE_PRIORITY_LOW),
- );
- $header['plugin'] = array(
- 'data' => $this->t('Type'),
- 'class' => array(RESPONSIVE_PRIORITY_LOW),
- );
- $header['status'] = array(
- 'data' => $this->t('Status'),
- 'class' => array(RESPONSIVE_PRIORITY_LOW),
- );
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- /** @var $entity \Drupal\search\SearchPageInterface */
- $row['label'] = $this->getLabel($entity);
- $row['url']['#markup'] = 'search/' . $entity->getPath();
- // If the search page is active, link to it.
- if ($entity->status()) {
- $row['url'] = array(
- '#type' => 'link',
- '#title' => $row['url'],
- '#route_name' => 'search.view_' . $entity->id(),
- );
- }
-
- $definition = $entity->getPlugin()->getPluginDefinition();
- $row['plugin']['#markup'] = $definition['title'];
-
- if ($entity->isDefaultSearch()) {
- $status = $this->t('Default');
- }
- elseif ($entity->status()) {
- $status = $this->t('Enabled');
- }
- else {
- $status = $this->t('Disabled');
- }
- $row['status']['#markup'] = $status;
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildForm(array $form, array &$form_state) {
- $form = parent::buildForm($form, $form_state);
- $old_state = $this->configFactory->getOverrideState();
- $search_settings = $this->configFactory->setOverrideState(FALSE)->get('search.settings');
- $this->configFactory->setOverrideState($old_state);
- // Collect some stats.
- $remaining = 0;
- $total = 0;
- foreach ($this->entities as $entity) {
- if ($entity->isIndexable() && $status = $entity->getPlugin()->indexStatus()) {
- $remaining += $status['remaining'];
- $total += $status['total'];
- }
- }
-
- $this->moduleHandler->loadAllIncludes('admin.inc');
- $count = format_plural($remaining, 'There is 1 item left to index.', 'There are @count items left to index.');
- $percentage = ((int) min(100, 100 * ($total - $remaining) / max(1, $total))) . '%';
- $status = '' . $this->t('%percentage of the site has been indexed.', array('%percentage' => $percentage)) . ' ' . $count . '
';
- $form['status'] = array(
- '#type' => 'details',
- '#title' => $this->t('Indexing status'),
- '#open' => TRUE,
- );
- $form['status']['status'] = array('#markup' => $status);
- $form['status']['wipe'] = array(
- '#type' => 'submit',
- '#value' => $this->t('Re-index site'),
- '#submit' => array(array($this, 'searchAdminReindexSubmit')),
- );
-
- $items = array(10, 20, 50, 100, 200, 500);
- $items = array_combine($items, $items);
-
- // Indexing throttle:
- $form['indexing_throttle'] = array(
- '#type' => 'details',
- '#title' => $this->t('Indexing throttle'),
- '#open' => TRUE,
- );
- $form['indexing_throttle']['cron_limit'] = array(
- '#type' => 'select',
- '#title' => $this->t('Number of items to index per cron run'),
- '#default_value' => $search_settings->get('index.cron_limit'),
- '#options' => $items,
- '#description' => $this->t('The maximum number of items indexed in each pass of a cron maintenance task. If necessary, reduce the number of items to prevent timeouts and memory errors while indexing.', array('@cron' => url('admin/reports/status'))),
- );
- // Indexing settings:
- $form['indexing_settings'] = array(
- '#type' => 'details',
- '#title' => $this->t('Indexing settings'),
- '#open' => TRUE,
- );
- $form['indexing_settings']['info'] = array(
- '#markup' => $this->t('Changing the settings below will cause the site index to be rebuilt. The search index is not cleared but systematically updated to reflect the new settings. Searching will continue to work but new content won\'t be indexed until all existing content has been re-indexed.
The default settings should be appropriate for the majority of sites.
')
- );
- $form['indexing_settings']['minimum_word_size'] = array(
- '#type' => 'number',
- '#title' => $this->t('Minimum word length to index'),
- '#default_value' => $search_settings->get('index.minimum_word_size'),
- '#min' => 1,
- '#max' => 1000,
- '#description' => $this->t('The number of characters a word has to be to be indexed. A lower setting means better search result ranking, but also a larger database. Each search query must contain at least one keyword that is this size (or longer).')
- );
- $form['indexing_settings']['overlap_cjk'] = array(
- '#type' => 'checkbox',
- '#title' => $this->t('Simple CJK handling'),
- '#default_value' => $search_settings->get('index.overlap_cjk'),
- '#description' => $this->t('Whether to apply a simple Chinese/Japanese/Korean tokenizer based on overlapping sequences. Turn this off if you want to use an external preprocessor for this instead. Does not affect other languages.')
- );
-
- $form['search_pages'] = array(
- '#type' => 'details',
- '#title' => $this->t('Search pages'),
- '#open' => TRUE,
- );
- $form['search_pages']['add_page'] = array(
- '#type' => 'container',
- '#attributes' => array(
- 'class' => array('container-inline'),
- ),
- '#attached' => array(
- 'css' => array(
- drupal_get_path('module', 'search') . '/css/search.admin.css',
- ),
- ),
- );
- // In order to prevent validation errors for the parent form, this cannot be
- // required, see self::validateAddSearchPage().
- $form['search_pages']['add_page']['search_type'] = array(
- '#type' => 'select',
- '#title' => $this->t('Search page type'),
- '#empty_option' => $this->t('- Choose page type -'),
- '#options' => array_map(function ($definition) {
- return $definition['title'];
- }, $this->searchManager->getDefinitions()),
- );
- $form['search_pages']['add_page']['add_search_submit'] = array(
- '#type' => 'submit',
- '#value' => $this->t('Add new page'),
- '#validate' => array(array($this, 'validateAddSearchPage')),
- '#submit' => array(array($this, 'submitAddSearchPage')),
- '#limit_validation_errors' => array(array('search_type')),
- );
-
- // Move the listing into the search_pages element.
- $form['search_pages'][$this->entitiesKey] = $form[$this->entitiesKey];
- $form['search_pages'][$this->entitiesKey]['#empty'] = $this->t('No search pages have been configured.');
- unset($form[$this->entitiesKey]);
-
- $form['actions']['#type'] = 'actions';
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => $this->t('Save configuration'),
- '#button_type' => 'primary',
- );
-
- return $form;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- /** @var $entity \Drupal\search\SearchPageInterface */
- $operations = parent::getOperations($entity);
-
- // Prevent the default search from being disabled or deleted.
- if ($entity->isDefaultSearch()) {
- unset($operations['disable'], $operations['delete']);
- }
- else {
- $operations['default'] = array(
- 'title' => $this->t('Set as default'),
- 'route_name' => 'search.set_default',
- 'route_parameters' => array(
- 'search_page' => $entity->id(),
- ),
- 'weight' => 50,
- );
- }
-
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function validateForm(array &$form, array &$form_state) {
- }
-
- /**
- * {@inheritdoc}
- */
- public function submitForm(array &$form, array &$form_state) {
- parent::submitForm($form, $form_state);
-
- $search_settings = $this->configFactory->get('search.settings');
- // If these settings change, the index needs to be rebuilt.
- if (($search_settings->get('index.minimum_word_size') != $form_state['values']['minimum_word_size']) || ($search_settings->get('index.overlap_cjk') != $form_state['values']['overlap_cjk'])) {
- $search_settings->set('index.minimum_word_size', $form_state['values']['minimum_word_size']);
- $search_settings->set('index.overlap_cjk', $form_state['values']['overlap_cjk']);
- drupal_set_message($this->t('The index will be rebuilt.'));
- search_reindex();
- }
-
- $search_settings
- ->set('index.cron_limit', $form_state['values']['cron_limit'])
- ->save();
-
- drupal_set_message($this->t('The configuration options have been saved.'));
- }
-
- /**
- * Form submission handler for the reindex button on the search admin settings
- * form.
- */
- public function searchAdminReindexSubmit(array &$form, array &$form_state) {
- // Send the user to the confirmation page.
- $form_state['redirect_route']['route_name'] = 'search.reindex_confirm';
- }
-
- /**
- * Form validation handler for adding a new search page.
- */
- public function validateAddSearchPage(array &$form, array &$form_state) {
- if (empty($form_state['values']['search_type'])) {
- $this->formBuilder()->setErrorByName('search_type', $form_state, $this->t('You must select the new search page type.'));
- }
- }
-
- /**
- * Form submission handler for adding a new search page.
- */
- public function submitAddSearchPage(array &$form, array &$form_state) {
- $form_state['redirect_route'] = array(
- 'route_name' => 'search.add_type',
- 'route_parameters' => array(
- 'search_plugin_id' => $form_state['values']['search_type'],
- ),
- );
- }
-
-}
diff --git a/core/modules/search/lib/Drupal/search/SearchPageListController.php b/core/modules/search/lib/Drupal/search/SearchPageListController.php
new file mode 100644
index 0000000..a497507
--- /dev/null
+++ b/core/modules/search/lib/Drupal/search/SearchPageListController.php
@@ -0,0 +1,341 @@
+configFactory = $config_factory;
+ $this->searchManager = $search_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('plugin.manager.search'),
+ $container->get('config.factory')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormID() {
+ return 'search_admin_settings';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['label'] = array(
+ 'data' => $this->t('Label'),
+ );
+ $header['url'] = array(
+ 'data' => $this->t('URL'),
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ );
+ $header['plugin'] = array(
+ 'data' => $this->t('Type'),
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ );
+ $header['status'] = array(
+ 'data' => $this->t('Status'),
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ );
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ /** @var $entity \Drupal\search\SearchPageInterface */
+ $row['label'] = $this->getLabel($entity);
+ $row['url']['#markup'] = 'search/' . $entity->getPath();
+ // If the search page is active, link to it.
+ if ($entity->status()) {
+ $row['url'] = array(
+ '#type' => 'link',
+ '#title' => $row['url'],
+ '#route_name' => 'search.view_' . $entity->id(),
+ );
+ }
+
+ $definition = $entity->getPlugin()->getPluginDefinition();
+ $row['plugin']['#markup'] = $definition['title'];
+
+ if ($entity->isDefaultSearch()) {
+ $status = $this->t('Default');
+ }
+ elseif ($entity->status()) {
+ $status = $this->t('Enabled');
+ }
+ else {
+ $status = $this->t('Disabled');
+ }
+ $row['status']['#markup'] = $status;
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state) {
+ $form = parent::buildForm($form, $form_state);
+ $old_state = $this->configFactory->getOverrideState();
+ $search_settings = $this->configFactory->setOverrideState(FALSE)->get('search.settings');
+ $this->configFactory->setOverrideState($old_state);
+ // Collect some stats.
+ $remaining = 0;
+ $total = 0;
+ foreach ($this->entities as $entity) {
+ if ($entity->isIndexable() && $status = $entity->getPlugin()->indexStatus()) {
+ $remaining += $status['remaining'];
+ $total += $status['total'];
+ }
+ }
+
+ $this->moduleHandler->loadAllIncludes('admin.inc');
+ $count = format_plural($remaining, 'There is 1 item left to index.', 'There are @count items left to index.');
+ $percentage = ((int) min(100, 100 * ($total - $remaining) / max(1, $total))) . '%';
+ $status = '' . $this->t('%percentage of the site has been indexed.', array('%percentage' => $percentage)) . ' ' . $count . '
';
+ $form['status'] = array(
+ '#type' => 'details',
+ '#title' => $this->t('Indexing status'),
+ '#open' => TRUE,
+ );
+ $form['status']['status'] = array('#markup' => $status);
+ $form['status']['wipe'] = array(
+ '#type' => 'submit',
+ '#value' => $this->t('Re-index site'),
+ '#submit' => array(array($this, 'searchAdminReindexSubmit')),
+ );
+
+ $items = array(10, 20, 50, 100, 200, 500);
+ $items = array_combine($items, $items);
+
+ // Indexing throttle:
+ $form['indexing_throttle'] = array(
+ '#type' => 'details',
+ '#title' => $this->t('Indexing throttle'),
+ '#open' => TRUE,
+ );
+ $form['indexing_throttle']['cron_limit'] = array(
+ '#type' => 'select',
+ '#title' => $this->t('Number of items to index per cron run'),
+ '#default_value' => $search_settings->get('index.cron_limit'),
+ '#options' => $items,
+ '#description' => $this->t('The maximum number of items indexed in each pass of a cron maintenance task. If necessary, reduce the number of items to prevent timeouts and memory errors while indexing.', array('@cron' => url('admin/reports/status'))),
+ );
+ // Indexing settings:
+ $form['indexing_settings'] = array(
+ '#type' => 'details',
+ '#title' => $this->t('Indexing settings'),
+ '#open' => TRUE,
+ );
+ $form['indexing_settings']['info'] = array(
+ '#markup' => $this->t('Changing the settings below will cause the site index to be rebuilt. The search index is not cleared but systematically updated to reflect the new settings. Searching will continue to work but new content won\'t be indexed until all existing content has been re-indexed.
The default settings should be appropriate for the majority of sites.
')
+ );
+ $form['indexing_settings']['minimum_word_size'] = array(
+ '#type' => 'number',
+ '#title' => $this->t('Minimum word length to index'),
+ '#default_value' => $search_settings->get('index.minimum_word_size'),
+ '#min' => 1,
+ '#max' => 1000,
+ '#description' => $this->t('The number of characters a word has to be to be indexed. A lower setting means better search result ranking, but also a larger database. Each search query must contain at least one keyword that is this size (or longer).')
+ );
+ $form['indexing_settings']['overlap_cjk'] = array(
+ '#type' => 'checkbox',
+ '#title' => $this->t('Simple CJK handling'),
+ '#default_value' => $search_settings->get('index.overlap_cjk'),
+ '#description' => $this->t('Whether to apply a simple Chinese/Japanese/Korean tokenizer based on overlapping sequences. Turn this off if you want to use an external preprocessor for this instead. Does not affect other languages.')
+ );
+
+ $form['search_pages'] = array(
+ '#type' => 'details',
+ '#title' => $this->t('Search pages'),
+ '#open' => TRUE,
+ );
+ $form['search_pages']['add_page'] = array(
+ '#type' => 'container',
+ '#attributes' => array(
+ 'class' => array('container-inline'),
+ ),
+ '#attached' => array(
+ 'css' => array(
+ drupal_get_path('module', 'search') . '/css/search.admin.css',
+ ),
+ ),
+ );
+ // In order to prevent validation errors for the parent form, this cannot be
+ // required, see self::validateAddSearchPage().
+ $form['search_pages']['add_page']['search_type'] = array(
+ '#type' => 'select',
+ '#title' => $this->t('Search page type'),
+ '#empty_option' => $this->t('- Choose page type -'),
+ '#options' => array_map(function ($definition) {
+ return $definition['title'];
+ }, $this->searchManager->getDefinitions()),
+ );
+ $form['search_pages']['add_page']['add_search_submit'] = array(
+ '#type' => 'submit',
+ '#value' => $this->t('Add new page'),
+ '#validate' => array(array($this, 'validateAddSearchPage')),
+ '#submit' => array(array($this, 'submitAddSearchPage')),
+ '#limit_validation_errors' => array(array('search_type')),
+ );
+
+ // Move the listing into the search_pages element.
+ $form['search_pages'][$this->entitiesKey] = $form[$this->entitiesKey];
+ $form['search_pages'][$this->entitiesKey]['#empty'] = $this->t('No search pages have been configured.');
+ unset($form[$this->entitiesKey]);
+
+ $form['actions']['#type'] = 'actions';
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => $this->t('Save configuration'),
+ '#button_type' => 'primary',
+ );
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ /** @var $entity \Drupal\search\SearchPageInterface */
+ $operations = parent::getOperations($entity);
+
+ // Prevent the default search from being disabled or deleted.
+ if ($entity->isDefaultSearch()) {
+ unset($operations['disable'], $operations['delete']);
+ }
+ else {
+ $operations['default'] = array(
+ 'title' => $this->t('Set as default'),
+ 'route_name' => 'search.set_default',
+ 'route_parameters' => array(
+ 'search_page' => $entity->id(),
+ ),
+ 'weight' => 50,
+ );
+ }
+
+ return $operations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, array &$form_state) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ parent::submitForm($form, $form_state);
+
+ $search_settings = $this->configFactory->get('search.settings');
+ // If these settings change, the index needs to be rebuilt.
+ if (($search_settings->get('index.minimum_word_size') != $form_state['values']['minimum_word_size']) || ($search_settings->get('index.overlap_cjk') != $form_state['values']['overlap_cjk'])) {
+ $search_settings->set('index.minimum_word_size', $form_state['values']['minimum_word_size']);
+ $search_settings->set('index.overlap_cjk', $form_state['values']['overlap_cjk']);
+ drupal_set_message($this->t('The index will be rebuilt.'));
+ search_reindex();
+ }
+
+ $search_settings
+ ->set('index.cron_limit', $form_state['values']['cron_limit'])
+ ->save();
+
+ drupal_set_message($this->t('The configuration options have been saved.'));
+ }
+
+ /**
+ * Form submission handler for the reindex button on the search admin settings
+ * form.
+ */
+ public function searchAdminReindexSubmit(array &$form, array &$form_state) {
+ // Send the user to the confirmation page.
+ $form_state['redirect_route']['route_name'] = 'search.reindex_confirm';
+ }
+
+ /**
+ * Form validation handler for adding a new search page.
+ */
+ public function validateAddSearchPage(array &$form, array &$form_state) {
+ if (empty($form_state['values']['search_type'])) {
+ $this->formBuilder()->setErrorByName('search_type', $form_state, $this->t('You must select the new search page type.'));
+ }
+ }
+
+ /**
+ * Form submission handler for adding a new search page.
+ */
+ public function submitAddSearchPage(array &$form, array &$form_state) {
+ $form_state['redirect_route'] = array(
+ 'route_name' => 'search.add_type',
+ 'route_parameters' => array(
+ 'search_plugin_id' => $form_state['values']['search_type'],
+ ),
+ );
+ }
+
+}
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php b/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php
index f7f400c..fea529b 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php
@@ -20,7 +20,7 @@
* controllers = {
* "storage" = "Drupal\shortcut\ShortcutSetStorageController",
* "access" = "Drupal\shortcut\ShortcutSetAccessController",
- * "list_builder" = "Drupal\shortcut\ShortcutSetListBuilder",
+ * "list" = "Drupal\shortcut\ShortcutSetListController",
* "form" = {
* "default" = "Drupal\shortcut\ShortcutSetFormController",
* "add" = "Drupal\shortcut\ShortcutSetFormController",
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListBuilder.php b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListBuilder.php
deleted file mode 100644
index 45b6a5f..0000000
--- a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListBuilder.php
+++ /dev/null
@@ -1,52 +0,0 @@
- t('List links'),
- ) + $entity->urlInfo('customize-form');
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['name'] = $this->getLabel($entity);
- return $row + parent::buildRow($entity);
- }
-
-}
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php
new file mode 100644
index 0000000..6741ed2
--- /dev/null
+++ b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php
@@ -0,0 +1,50 @@
+ t('List links'),
+ ) + $entity->urlInfo('customize-form');
+ return $operations;
+ }
+
+ /**
+ * Overrides \Drupal\Core\Entity\EntityListController::buildRow().
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['name'] = $this->getLabel($entity);
+ return $row + parent::buildRow($entity);
+ }
+
+}
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index 8efa40a..3e8f51b 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -354,7 +354,6 @@ protected function drupalCreateContentType(array $values = array()) {
* - region: 'sidebar_first'.
* - theme: The default theme.
* - visibility: Empty array.
- * - cache: array('max_age' => 0).
*
* @return \Drupal\block\Entity\Block
* The block entity.
@@ -371,9 +370,6 @@ protected function drupalPlaceBlock($plugin_id, array $settings = array()) {
'label' => $this->randomName(8),
'visibility' => array(),
'weight' => 0,
- 'cache' => array(
- 'max_age' => 0,
- ),
);
foreach (array('region', 'id', 'theme', 'plugin', 'visibility', 'weight') as $key) {
$values[$key] = $settings[$key];
diff --git a/core/modules/system/entity.api.php b/core/modules/system/entity.api.php
index ab25a74..c0203bd 100644
--- a/core/modules/system/entity.api.php
+++ b/core/modules/system/entity.api.php
@@ -760,7 +760,7 @@ function hook_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\Entit
*
* @param array $operations
* Operations array as returned by
- * \Drupal\Core\Entity\EntityListBuilderInterface::getOperations().
+ * \Drupal\Core\Entity\EntityListControllerInterface::getOperations().
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity on which the linked operations will be performed.
*/
diff --git a/core/modules/system/lib/Drupal/system/DateFormatListBuilder.php b/core/modules/system/lib/Drupal/system/DateFormatListBuilder.php
deleted file mode 100644
index be83cd9..0000000
--- a/core/modules/system/lib/Drupal/system/DateFormatListBuilder.php
+++ /dev/null
@@ -1,88 +0,0 @@
-dateService = $date_service;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('date')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function load() {
- return array_filter(parent::load(), function ($entity) {
- return !$entity->isLocked();
- });
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['id'] = t('Machine name');
- $header['label'] = t('Name');
- $header['pattern'] = t('Pattern');
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['id'] = $entity->id();
- $row['label'] = $this->getLabel($entity);
- $row['pattern'] = $this->dateService->format(REQUEST_TIME, $entity->id());
- return $row + parent::buildRow($entity);
- }
-
-}
diff --git a/core/modules/system/lib/Drupal/system/DateFormatListController.php b/core/modules/system/lib/Drupal/system/DateFormatListController.php
new file mode 100644
index 0000000..9472d8c
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/DateFormatListController.php
@@ -0,0 +1,86 @@
+dateService = $date_service;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('date')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load() {
+ return array_filter(parent::load(), function ($entity) {
+ return !$entity->isLocked();
+ });
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['id'] = t('Machine name');
+ $header['label'] = t('Name');
+ $header['pattern'] = t('Pattern');
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['id'] = $entity->id();
+ $row['label'] = $this->getLabel($entity);
+ $row['pattern'] = $this->dateService->format(REQUEST_TIME, $entity->id());
+ return $row + parent::buildRow($entity);
+ }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Entity/DateFormat.php b/core/modules/system/lib/Drupal/system/Entity/DateFormat.php
index 21d8035..a03cac3 100644
--- a/core/modules/system/lib/Drupal/system/Entity/DateFormat.php
+++ b/core/modules/system/lib/Drupal/system/Entity/DateFormat.php
@@ -20,7 +20,7 @@
* label = @Translation("Date format"),
* controllers = {
* "access" = "Drupal\system\DateFormatAccessController",
- * "list_builder" = "Drupal\system\DateFormatListBuilder",
+ * "list" = "Drupal\system\DateFormatListController",
* "form" = {
* "add" = "Drupal\system\Form\DateFormatAddForm",
* "edit" = "Drupal\system\Form\DateFormatEditForm",
diff --git a/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php b/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php
index 27d628a..fe689d0 100644
--- a/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php
@@ -79,12 +79,10 @@ public function buildForm(array $form, array &$form_state) {
'#title' => t('Caching'),
'#open' => TRUE,
);
- // Identical options to the ones for block caching.
- // @see \Drupal\block\BlockBase::buildConfigurationForm()
+
$period = array(0, 60, 180, 300, 600, 900, 1800, 2700, 3600, 10800, 21600, 32400, 43200, 86400);
$period = array_map('format_interval', array_combine($period, $period));
- $period[0] = '<' . t('no caching') . '>';
- $period[\Drupal\Core\Cache\Cache::PERMANENT] = t('Forever');
+ $period[0] = '<' . t('none') . '>';
$form['caching']['page_cache_maximum_age'] = array(
'#type' => 'select',
'#title' => t('Page cache maximum age'),
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php
index c594b98..f669e61 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemHelpBlock.php
@@ -117,24 +117,4 @@ public function build() {
);
}
- /**
- * {@inheritdoc}
- */
- public function defaultConfiguration() {
- // Modify the default max age for the System Help block: help text is static
- // for a given URL, except when a module is updated, in which case
- // update.php must be run, which clears all caches. Thus it's safe to cache
- // the output for this block forever on a per-URL basis.
- return array('cache' => array('max_age' => \Drupal\Core\Cache\Cache::PERMANENT));
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getRequiredCacheContexts() {
- // The "System Help" block must be cached per URL: help is defined for a
- // given path, and does not come with any access restrictions.
- return array('cache_context.url');
- }
-
}
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMainBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMainBlock.php
index 666b515..a64951a 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMainBlock.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMainBlock.php
@@ -28,26 +28,4 @@ public function build() {
);
}
- /**
- * {@inheritdoc}
- */
- public function buildConfigurationForm(array $form, array &$form_state) {
- $form = parent::buildConfigurationForm($form, $form_state);
-
- // The main content block is never cacheable, because it may be dynamic.
- $form['cache']['#disabled'] = TRUE;
- $form['cache']['#description'] = t('This block is never cacheable, it is not configurable.');
- $form['cache']['max_age']['#value'] = 0;
-
- return $form;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isCacheable() {
- // The main content block is never cacheable, because it may be dynamic.
- return FALSE;
- }
-
}
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
index 15cb1d8..8298193 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
@@ -7,8 +7,8 @@
namespace Drupal\system\Plugin\Block;
-use Drupal\Component\Utility\NestedArray;
use Drupal\block\BlockBase;
+use Drupal\Core\Session\AccountInterface;
/**
* Provides a generic Menu block.
@@ -30,41 +30,4 @@ public function build() {
return menu_tree($menu);
}
- /**
- * {@inheritdoc}
- */
- public function defaultConfiguration() {
- // Modify the default max age for menu blocks: modifications made to menus,
- // menu links and menu blocks will automatically invalidate corresponding
- // cache tags, therefore allowing us to cache menu blocks forever. This is
- // only not the case if there are user-specific or dynamic alterations (e.g.
- // hook_node_access()), but in that:
- // 1) it is possible to set a different max age for individual blocks, since
- // this is just the default value.
- // 2) modules can modify caching by implementing hook_block_view_alter()
- return array('cache' => array('max_age' => \Drupal\Core\Cache\Cache::PERMANENT));
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCacheTags() {
- // Even when the menu block renders to the empty string for a user, we want
- // the cache tag for this menu to be set: whenever the menu is changed, this
- // menu block must also be re-rendered for that user, because maybe a menu
- // link that is accessible for that user has been added.
- $tags = array('menu' => array($this->getDerivativeId()));
- return NestedArray::mergeDeep(parent::getCacheTags(), $tags);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getRequiredCacheContexts() {
- // Menu blocks must be cached per URL and per role: the "active" menu link
- // may differ per URL and different roles may have access to different menu
- // links.
- return array('cache_context.url', 'cache_context.user.roles');
- }
-
}
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemPoweredByBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemPoweredByBlock.php
index b0878f8..742af7b 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemPoweredByBlock.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemPoweredByBlock.php
@@ -8,7 +8,6 @@
namespace Drupal\system\Plugin\Block;
use Drupal\block\BlockBase;
-use Drupal\Core\Cache\Cache;
/**
* Provides a 'Powered by Drupal' block.
@@ -27,34 +26,4 @@ public function build() {
return array('#markup' => '' . t('Powered by Drupal', array('@poweredby' => 'http://drupal.org')) . '');
}
-
- /**
- * {@inheritdoc}
- */
- public function buildConfigurationForm(array $form, array &$form_state) {
- $form = parent::buildConfigurationForm($form, $form_state);
-
- // The 'Powered by Drupal' block is permanently cacheable, because its
- // contents can never change.
- $form['cache']['#disabled'] = TRUE;
- $form['cache']['max_age']['#value'] = Cache::PERMANENT;
- $form['cache']['#description'] = t('This block is always cached forever, it is not configurable.');
-
- return $form;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCacheMaxAge() {
- return Cache::PERMANENT;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isCacheable() {
- return TRUE;
- }
-
}
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php
index 72a4c49..372de9b 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php
@@ -52,6 +52,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
foreach ($this->menuStorage->loadMultiple() as $menu => $entity) {
$this->derivatives[$menu] = $base_plugin_definition;
$this->derivatives[$menu]['admin_label'] = $entity->label();
+ $this->derivatives[$menu]['cache'] = DRUPAL_NO_CACHE;
}
return $this->derivatives;
}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Cache/PageCacheTagsIntegrationTest.php b/core/modules/system/lib/Drupal/system/Tests/Cache/PageCacheTagsIntegrationTest.php
index cc584a3..b245c34 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Cache/PageCacheTagsIntegrationTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Cache/PageCacheTagsIntegrationTest.php
@@ -64,35 +64,13 @@ function testPageCacheTags() {
'promote' => NODE_PROMOTED,
));
- // Place a block, but only make it visible on full node page 2.
- $block = $this->drupalPlaceBlock('views_block:comments_recent-block_1', array(
- 'visibility' => array(
- 'path' => array(
- 'visibility' => BLOCK_VISIBILITY_LISTED,
- 'pages' => 'node/' . $node_2->id(),
- ),
- )
- ));
-
// Full node page 1.
$this->verifyPageCacheTags('node/' . $node_1->id(), array(
'content:1',
- 'block_view:1',
- 'block:bartik_content',
- 'block:bartik_tools',
- 'block:bartik_login',
- 'block:bartik_footer',
- 'block:bartik_powered',
- 'block_plugin:system_main_block',
- 'block_plugin:system_menu_block__tools',
- 'block_plugin:user_login_block',
- 'block_plugin:system_menu_block__footer',
- 'block_plugin:system_powered_by_block',
'node_view:1',
'node:' . $node_1->id(),
'user:' . $author_1->id(),
'filter_format:basic_html',
- 'menu:tools',
'menu:footer',
'menu:main',
));
@@ -100,24 +78,10 @@ function testPageCacheTags() {
// Full node page 2.
$this->verifyPageCacheTags('node/' . $node_2->id(), array(
'content:1',
- 'block_view:1',
- 'block:bartik_content',
- 'block:bartik_tools',
- 'block:bartik_login',
- 'block:' . $block->id(),
- 'block:bartik_footer',
- 'block:bartik_powered',
- 'block_plugin:system_main_block',
- 'block_plugin:system_menu_block__tools',
- 'block_plugin:user_login_block',
- 'block_plugin:views_block__comments_recent-block_1',
- 'block_plugin:system_menu_block__footer',
- 'block_plugin:system_powered_by_block',
'node_view:1',
'node:' . $node_2->id(),
'user:' . $author_2->id(),
'filter_format:full_html',
- 'menu:tools',
'menu:footer',
'menu:main',
));
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewBuilderTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewBuilderTest.php
index 0379aa7..2d0369b 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewBuilderTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityViewBuilderTest.php
@@ -144,7 +144,7 @@ public function testEntityViewBuilderCacheToggling() {
// Test a view mode in default conditions: render caching is enabled for
// the entity type and the view mode.
$build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test, 'full');
- $this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == array('tags', 'keys', 'bin') , 'A view mode with render cache enabled has the correct output (cache tags, keys and bin).');
+ $this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == array('tags', 'keys', 'granularity', 'bin') , 'A view mode with render cache enabled has the correct output (cache tags, keys, granularity and bin).');
// Test that a view mode can opt out of render caching.
$build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test, 'test');
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
index 357b77e..d55bb8d 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
@@ -22,7 +22,7 @@
* id = "entity_test",
* label = @Translation("Test entity"),
* controllers = {
- * "list_builder" = "Drupal\entity_test\EntityTestListBuilder",
+ * "list" = "Drupal\entity_test\EntityTestListController",
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
* "access" = "Drupal\entity_test\EntityTestAccessController",
* "form" = {
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestListBuilder.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestListBuilder.php
deleted file mode 100644
index 1fbc8a1..0000000
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestListBuilder.php
+++ /dev/null
@@ -1,38 +0,0 @@
-getLabel($entity);
- $row['id'] = $entity->id();
- return $row + parent::buildRow($entity);
- }
-
-}
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestListController.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestListController.php
new file mode 100644
index 0000000..fddc724
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestListController.php
@@ -0,0 +1,36 @@
+getLabel($entity);
+ $row['id'] = $entity->id();
+ return $row + parent::buildRow($entity);
+ }
+
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
index f7e3f91..ee3d8f3 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
@@ -20,7 +20,7 @@
* label = @Translation("Taxonomy vocabulary"),
* controllers = {
* "storage" = "Drupal\taxonomy\VocabularyStorageController",
- * "list_builder" = "Drupal\taxonomy\VocabularyListBuilder",
+ * "list" = "Drupal\taxonomy\VocabularyListController",
* "form" = {
* "default" = "Drupal\taxonomy\VocabularyFormController",
* "reset" = "Drupal\taxonomy\Form\VocabularyResetForm",
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyListBuilder.php b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyListBuilder.php
deleted file mode 100644
index 2823551..0000000
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyListBuilder.php
+++ /dev/null
@@ -1,106 +0,0 @@
- t('list terms'),
- 'weight' => 0,
- ) + $entity->urlInfo('overview-form');
- $operations['add'] = array(
- 'title' => t('add terms'),
- 'weight' => 10,
- ) + $entity->urlInfo('add-form');
- unset($operations['delete']);
-
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header['label'] = t('Vocabulary name');
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['label'] = $this->getLabel($entity);
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function render() {
- $entities = $this->load();
- // If there are not multiple vocabularies, disable dragging by unsetting the
- // weight key.
- if (count($entities) <= 1) {
- unset($this->weightKey);
- }
- $build = parent::render();
- $build['#empty'] = t('No vocabularies available. Add vocabulary.', array('@link' => url('admin/structure/taxonomy/add')));
- return $build;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildForm(array $form, array &$form_state) {
- $form = parent::buildForm($form, $form_state);
- $form['vocabularies']['#attributes'] = array('id' => 'taxonomy');
- $form['actions']['submit']['#value'] = t('Save');
-
- return $form;
- }
-
- /**
- * {@inheritdoc}
- */
- public function submitForm(array &$form, array &$form_state) {
- parent::submitForm($form, $form_state);
-
- drupal_set_message(t('The configuration options have been saved.'));
- }
-
-}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyListController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyListController.php
new file mode 100644
index 0000000..104b360
--- /dev/null
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyListController.php
@@ -0,0 +1,104 @@
+ t('list terms'),
+ 'weight' => 0,
+ ) + $entity->urlInfo('overview-form');
+ $operations['add'] = array(
+ 'title' => t('add terms'),
+ 'weight' => 10,
+ ) + $entity->urlInfo('add-form');
+ unset($operations['delete']);
+
+ return $operations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header['label'] = t('Vocabulary name');
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['label'] = $this->getLabel($entity);
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ $entities = $this->load();
+ // If there are not multiple vocabularies, disable dragging by unsetting the
+ // weight key.
+ if (count($entities) <= 1) {
+ unset($this->weightKey);
+ }
+ $build = parent::render();
+ $build['#empty'] = t('No vocabularies available. Add vocabulary.', array('@link' => url('admin/structure/taxonomy/add')));
+ return $build;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state) {
+ $form = parent::buildForm($form, $form_state);
+ $form['vocabularies']['#attributes'] = array('id' => 'taxonomy');
+ $form['actions']['submit']['#value'] = t('Save');
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ parent::submitForm($form, $form_state);
+
+ drupal_set_message(t('The configuration options have been saved.'));
+ }
+
+}
diff --git a/core/modules/user/lib/Drupal/user/Cache/UserCacheContext.php b/core/modules/user/lib/Drupal/user/Cache/UserCacheContext.php
deleted file mode 100644
index d9d880e..0000000
--- a/core/modules/user/lib/Drupal/user/Cache/UserCacheContext.php
+++ /dev/null
@@ -1,42 +0,0 @@
-user = $user;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function getLabel() {
- return t('User');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getContext() {
- return "u." . $this->user->id();
- }
-
-}
diff --git a/core/modules/user/lib/Drupal/user/Cache/UserRolesCacheContext.php b/core/modules/user/lib/Drupal/user/Cache/UserRolesCacheContext.php
deleted file mode 100644
index 0f7975d..0000000
--- a/core/modules/user/lib/Drupal/user/Cache/UserRolesCacheContext.php
+++ /dev/null
@@ -1,42 +0,0 @@
-user = $user;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function getLabel() {
- return t("User's roles");
- }
-
- /**
- * {@inheritdoc}
- */
- public function getContext() {
- return 'r.' . implode(',', $this->user->getRoles());
- }
-
-}
diff --git a/core/modules/user/lib/Drupal/user/Controller/UserListController.php b/core/modules/user/lib/Drupal/user/Controller/UserListController.php
new file mode 100644
index 0000000..72c1a84
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/Controller/UserListController.php
@@ -0,0 +1,160 @@
+queryFactory = $query_factory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+ return new static(
+ $entity_type,
+ $container->get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('entity.query')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load() {
+ $entity_query = $this->queryFactory->get('user');
+ $entity_query->condition('uid', 0, '<>');
+ $entity_query->pager(50);
+ $header = $this->buildHeader();
+ $entity_query->tableSort($header);
+ $uids = $entity_query->execute();
+ return $this->storage->loadMultiple($uids);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ $header = array(
+ 'username' => array(
+ 'data' => $this->t('Username'),
+ 'field' => 'name',
+ 'specifier' => 'name',
+ ),
+ 'status' => array(
+ 'data' => $this->t('Status'),
+ 'field' => 'status',
+ 'specifier' => 'status',
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ ),
+ 'roles' => array(
+ 'data' => $this->t('Roles'),
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ ),
+ 'member_for' => array(
+ 'data' => $this->t('Member for'),
+ 'field' => 'created',
+ 'specifier' => 'created',
+ 'sort' => 'desc',
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ ),
+ 'access' => array(
+ 'data' => $this->t('Last access'),
+ 'field' => 'access',
+ 'specifier' => 'access',
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ ),
+ );
+ return $header + parent::buildHeader();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $entity) {
+ $row['username']['data'] = array(
+ '#theme' => 'username',
+ '#account' => $entity,
+ );
+ $row['status'] = $entity->isActive() ? $this->t('active') : $this->t('blocked');
+
+ $roles = array_map('\Drupal\Component\Utility\String::checkPlain', user_role_names(TRUE));
+ unset($roles[DRUPAL_AUTHENTICATED_RID]);
+ $users_roles = array();
+ foreach ($entity->getRoles() as $role) {
+ if (isset($roles[$role])) {
+ $users_roles[] = $roles[$role];
+ }
+ }
+ asort($users_roles);
+ $row['roles']['data'] = array(
+ '#theme' => 'item_list',
+ '#items' => $users_roles,
+ );
+ $row['member_for'] = format_interval(REQUEST_TIME - $entity->getCreatedTime());
+ $row['access'] = $entity->access ? $this->t('@time ago', array(
+ '@time' => format_interval(REQUEST_TIME - $entity->getLastAccessedTime()),
+ )) : t('never');
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+ if (isset($operations['edit'])) {
+ $destination = drupal_get_destination();
+ $operations['edit']['query'] = $destination;
+ }
+ return $operations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ $build['accounts'] = parent::render();
+ $build['accounts']['#empty'] = $this->t('No people available.');
+ $build['pager']['#theme'] = 'pager';
+ return $build;
+ }
+
+}
diff --git a/core/modules/user/lib/Drupal/user/Entity/Role.php b/core/modules/user/lib/Drupal/user/Entity/Role.php
index 0ce5186..2a025d9 100644
--- a/core/modules/user/lib/Drupal/user/Entity/Role.php
+++ b/core/modules/user/lib/Drupal/user/Entity/Role.php
@@ -21,7 +21,7 @@
* controllers = {
* "storage" = "Drupal\user\RoleStorageController",
* "access" = "Drupal\user\RoleAccessController",
- * "list_builder" = "Drupal\user\RoleListBuilder",
+ * "list" = "Drupal\user\RoleListController",
* "form" = {
* "default" = "Drupal\user\RoleFormController",
* "delete" = "Drupal\user\Form\UserRoleDelete"
diff --git a/core/modules/user/lib/Drupal/user/Entity/User.php b/core/modules/user/lib/Drupal/user/Entity/User.php
index 8cac65c..49c66fd 100644
--- a/core/modules/user/lib/Drupal/user/Entity/User.php
+++ b/core/modules/user/lib/Drupal/user/Entity/User.php
@@ -24,7 +24,7 @@
* controllers = {
* "storage" = "Drupal\user\UserStorageController",
* "access" = "Drupal\user\UserAccessController",
- * "list_builder" = "Drupal\user\UserListBuilder",
+ * "list" = "Drupal\user\Controller\UserListController",
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "form" = {
* "default" = "Drupal\user\ProfileFormController",
diff --git a/core/modules/user/lib/Drupal/user/RoleListBuilder.php b/core/modules/user/lib/Drupal/user/RoleListBuilder.php
deleted file mode 100644
index 2d2b9be..0000000
--- a/core/modules/user/lib/Drupal/user/RoleListBuilder.php
+++ /dev/null
@@ -1,67 +0,0 @@
-getLabel($entity);
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
-
- if ($entity->hasLinkTemplate('edit-permissions-form')) {
- $operations['permissions'] = array(
- 'title' => t('Edit permissions'),
- 'weight' => 20,
- ) + $entity->urlInfo('edit-permissions-form');
- }
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function submitForm(array &$form, array &$form_state) {
- parent::submitForm($form, $form_state);
-
- drupal_set_message(t('The role settings have been updated.'));
- }
-
-}
diff --git a/core/modules/user/lib/Drupal/user/RoleListController.php b/core/modules/user/lib/Drupal/user/RoleListController.php
new file mode 100644
index 0000000..c2cd9b9
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/RoleListController.php
@@ -0,0 +1,65 @@
+getLabel($entity);
+ return $row + parent::buildRow($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+
+ if ($entity->hasLinkTemplate('edit-permissions-form')) {
+ $operations['permissions'] = array(
+ 'title' => t('Edit permissions'),
+ 'weight' => 20,
+ ) + $entity->urlInfo('edit-permissions-form');
+ }
+ return $operations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ parent::submitForm($form, $form_state);
+
+ drupal_set_message(t('The role settings have been updated.'));
+ }
+
+}
diff --git a/core/modules/user/lib/Drupal/user/UserListBuilder.php b/core/modules/user/lib/Drupal/user/UserListBuilder.php
deleted file mode 100644
index d2fcd3a..0000000
--- a/core/modules/user/lib/Drupal/user/UserListBuilder.php
+++ /dev/null
@@ -1,159 +0,0 @@
-queryFactory = $query_factory;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('entity.query')
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function load() {
- $entity_query = $this->queryFactory->get('user');
- $entity_query->condition('uid', 0, '<>');
- $entity_query->pager(50);
- $header = $this->buildHeader();
- $entity_query->tableSort($header);
- $uids = $entity_query->execute();
- return $this->storage->loadMultiple($uids);
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- $header = array(
- 'username' => array(
- 'data' => $this->t('Username'),
- 'field' => 'name',
- 'specifier' => 'name',
- ),
- 'status' => array(
- 'data' => $this->t('Status'),
- 'field' => 'status',
- 'specifier' => 'status',
- 'class' => array(RESPONSIVE_PRIORITY_LOW),
- ),
- 'roles' => array(
- 'data' => $this->t('Roles'),
- 'class' => array(RESPONSIVE_PRIORITY_LOW),
- ),
- 'member_for' => array(
- 'data' => $this->t('Member for'),
- 'field' => 'created',
- 'specifier' => 'created',
- 'sort' => 'desc',
- 'class' => array(RESPONSIVE_PRIORITY_LOW),
- ),
- 'access' => array(
- 'data' => $this->t('Last access'),
- 'field' => 'access',
- 'specifier' => 'access',
- 'class' => array(RESPONSIVE_PRIORITY_LOW),
- ),
- );
- return $header + parent::buildHeader();
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $entity) {
- $row['username']['data'] = array(
- '#theme' => 'username',
- '#account' => $entity,
- );
- $row['status'] = $entity->isActive() ? $this->t('active') : $this->t('blocked');
-
- $roles = array_map('\Drupal\Component\Utility\String::checkPlain', user_role_names(TRUE));
- unset($roles[DRUPAL_AUTHENTICATED_RID]);
- $users_roles = array();
- foreach ($entity->getRoles() as $role) {
- if (isset($roles[$role])) {
- $users_roles[] = $roles[$role];
- }
- }
- asort($users_roles);
- $row['roles']['data'] = array(
- '#theme' => 'item_list',
- '#items' => $users_roles,
- );
- $row['member_for'] = format_interval(REQUEST_TIME - $entity->getCreatedTime());
- $row['access'] = $entity->access ? $this->t('@time ago', array(
- '@time' => format_interval(REQUEST_TIME - $entity->getLastAccessedTime()),
- )) : t('never');
- return $row + parent::buildRow($entity);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
- if (isset($operations['edit'])) {
- $destination = drupal_get_destination();
- $operations['edit']['query'] = $destination;
- }
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function render() {
- $build['accounts'] = parent::render();
- $build['accounts']['#empty'] = $this->t('No people available.');
- $build['pager']['#theme'] = 'pager';
- return $build;
- }
-
-}
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index 17229ed..bfd7ad1 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -15,16 +15,6 @@ services:
class: Drupal\user\Access\LoginStatusCheck
tags:
- { name: access_check, applies_to: _user_is_logged_in }
- cache_context.user:
- class: Drupal\user\Cache\UserCacheContext
- arguments: ['@current_user']
- tags:
- - { name: cache.context}
- cache_context.user.roles:
- class: Drupal\user\Cache\UserRolesCacheContext
- arguments: ['@current_user']
- tags:
- - { name: cache.context}
user.data:
class: Drupal\user\UserData
arguments: ['@database']
diff --git a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php
index 2648919..482c25f 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php
@@ -29,11 +29,13 @@ public function build() {
$this->view->display_handler->preBlockBuild($this);
if ($output = $this->view->executeDisplay($this->displayID)) {
- // Override the label to the dynamic title configured in the view.
- if (empty($this->configuration['views_label']) && $this->view->getTitle()) {
- $output['#title'] = Xss::filterAdmin($this->view->getTitle());
+ // Set the label to the title configured in the view.
+ if (empty($this->configuration['views_label'])) {
+ $this->configuration['label'] = Xss::filterAdmin($this->view->getTitle());
+ }
+ else {
+ $this->configuration['label'] = $this->configuration['views_label'];
}
-
// Before returning the block output, convert it to a renderable array
// with contextual links.
$this->addContextualLinks($output);
@@ -46,20 +48,6 @@ public function build() {
/**
* {@inheritdoc}
*/
- public function getConfiguration() {
- $configuration = parent::getConfiguration();
-
- // Set the label to the static title configured in the view.
- if (!empty($configuration['views_label'])) {
- $configuration['label'] = $configuration['views_label'];
- }
-
- return $configuration;
- }
-
- /**
- * {@inheritdoc}
- */
public function defaultConfiguration() {
$settings = parent::defaultConfiguration();
diff --git a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlockBase.php b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlockBase.php
index 3c228d1..56f3c86 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlockBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlockBase.php
@@ -99,7 +99,10 @@ public function access(AccountInterface $account) {
* {@inheritdoc}
*/
public function defaultConfiguration() {
- return array('views_label' => '');
+ $settings = array();
+ $settings['views_label'] = '';
+
+ return $settings;
}
/**
diff --git a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php
index 9541124..a7fb041 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php
@@ -102,6 +102,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
$this->derivatives[$delta] = array(
'category' => $display->getOption('block_category'),
'admin_label' => $desc,
+ 'cache' => $display->getCacheType()
);
$this->derivatives[$delta] += $base_plugin_definition;
}
diff --git a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php
index 29439a6..0423bb5 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php
@@ -93,6 +93,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
$desc = t('Exposed form: @view-@display_id', array('@view' => $view->id(), '@display_id' => $display->display['id']));
$this->derivatives[$delta] = array(
'admin_label' => $desc,
+ 'cache' => DRUPAL_NO_CACHE,
);
$this->derivatives[$delta] += $base_plugin_definition;
}
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
index b18fff3..bc99b02 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
@@ -2383,6 +2383,7 @@ public function getSpecialBlocks() {
$blocks[$delta] = array(
'info' => $desc,
+ 'cache' => DRUPAL_NO_CACHE,
);
}
diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayFeedTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayFeedTest.php
index fe101d8..484734e 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayFeedTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayFeedTest.php
@@ -51,7 +51,7 @@ protected function setUp() {
public function testFeedUI() {
$this->drupalGet('admin/structure/views');
// Verify that the page lists the test_display_feed view.
- // Regression test: ViewListBuilder::getDisplayPaths() did not properly
+ // Regression test: ViewsListController::getDisplayPaths() did not properly
// check whether a DisplayBag was returned in iterating over all displays.
$this->assertText('test_display_feed');
diff --git a/core/modules/views/tests/Drupal/views/Tests/Plugin/Block/ViewsBlockTest.php b/core/modules/views/tests/Drupal/views/Tests/Plugin/Block/ViewsBlockTest.php
index ff9bc33..51254b5 100644
--- a/core/modules/views/tests/Drupal/views/Tests/Plugin/Block/ViewsBlockTest.php
+++ b/core/modules/views/tests/Drupal/views/Tests/Plugin/Block/ViewsBlockTest.php
@@ -15,6 +15,9 @@
if (!defined('BLOCK_LABEL_VISIBLE')) {
define('BLOCK_LABEL_VISIBLE', 'visible');
}
+if (!defined('DRUPAL_NO_CACHE')) {
+ define('DRUPAL_NO_CACHE', -1);
+}
/**
* Tests the views block plugin.
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Controller/ViewsUIController.php b/core/modules/views_ui/lib/Drupal/views_ui/Controller/ViewsUIController.php
index cc6b037..018d4d9 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Controller/ViewsUIController.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Controller/ViewsUIController.php
@@ -154,7 +154,7 @@ public function ajaxOperation(ViewStorageInterface $view, $op, Request $request)
// If the request is via AJAX, return the rendered list as JSON.
if ($request->request->get('js')) {
- $list = $this->entityManager()->getListBuilder('view')->render();
+ $list = $this->entityManager()->getListController('view')->render();
$response = new AjaxResponse();
$response->addCommand(new ReplaceCommand('#views-entity-list', drupal_render($list)));
return $response;
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewListBuilder.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewListBuilder.php
deleted file mode 100644
index 36f20c3..0000000
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewListBuilder.php
+++ /dev/null
@@ -1,268 +0,0 @@
-get('entity.manager')->getStorageController($entity_type->id()),
- $container->get('plugin.manager.views.display')
- );
- }
-
- /**
- * Constructs a new ViewListBuilder object.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type definition.
- * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage.
- * The entity storage controller class.
- * @param \Drupal\Component\Plugin\PluginManagerInterface $display_manager
- * The views display plugin manager to use.
- */
- public function __construct(EntityTypeInterface $entity_type, EntityStorageControllerInterface $storage, PluginManagerInterface $display_manager) {
- parent::__construct($entity_type, $storage);
-
- $this->displayManager = $display_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public function load() {
- $entities = array(
- 'enabled' => array(),
- 'disabled' => array(),
- );
- foreach (parent::load() as $entity) {
- if ($entity->status()) {
- $entities['enabled'][] = $entity;
- }
- else {
- $entities['disabled'][] = $entity;
- }
- }
- return $entities;
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildRow(EntityInterface $view) {
- $row = parent::buildRow($view);
- return array(
- 'data' => array(
- 'view_name' => array(
- 'data' => array(
- '#theme' => 'views_ui_view_info',
- '#view' => $view,
- '#displays' => $this->getDisplaysList($view)
- ),
- ),
- 'description' => array(
- 'data' => array(
- '#markup' => String::checkPlain($view->get('description')),
- ),
- 'class' => array('views-table-filter-text-source'),
- ),
- 'tag' => $view->get('tag'),
- 'path' => implode(', ', $this->getDisplayPaths($view)),
- 'operations' => $row['operations'],
- ),
- 'title' => $this->t('Machine name: @name', array('@name' => $view->id())),
- 'class' => array($view->status() ? 'views-ui-list-enabled' : 'views-ui-list-disabled'),
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildHeader() {
- return array(
- 'view_name' => array(
- 'data' => $this->t('View name'),
- 'class' => array('views-ui-name'),
- ),
- 'description' => array(
- 'data' => $this->t('Description'),
- 'class' => array('views-ui-description'),
- ),
- 'tag' => array(
- 'data' => $this->t('Tag'),
- 'class' => array('views-ui-tag'),
- ),
- 'path' => array(
- 'data' => $this->t('Path'),
- 'class' => array('views-ui-path'),
- ),
- 'operations' => array(
- 'data' => $this->t('Operations'),
- 'class' => array('views-ui-operations'),
- ),
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = parent::getOperations($entity);
-
- if ($entity->hasLinkTemplate('clone')) {
- $operations['clone'] = array(
- 'title' => $this->t('Clone'),
- 'weight' => 15,
- ) + $entity->urlInfo('clone');
- }
-
- // Add AJAX functionality to enable/disable operations.
- foreach (array('enable', 'disable') as $op) {
- if (isset($operations[$op])) {
- $operations[$op]['route_name'] = "views_ui.$op";
- $operations[$op]['route_parameters'] = array('view' => $entity->id());
-
- // Enable and disable operations should use AJAX.
- $operations[$op]['attributes']['class'][] = 'use-ajax';
- }
- }
-
- return $operations;
- }
-
- /**
- * {@inheritdoc}
- */
- public function render() {
- $entities = $this->load();
- $list['#type'] = 'container';
- $list['#attributes']['id'] = 'views-entity-list';
-
- $list['#attached']['css'] = ViewFormControllerBase::getAdminCSS();
- $list['#attached']['library'][] = 'core/drupal.ajax';
- $list['#attached']['library'][] = 'views_ui/views_ui.listing';
-
- $form['filters'] = array(
- '#type' => 'container',
- '#attributes' => array(
- 'class' => array('table-filter', 'js-show'),
- ),
- );
-
- $list['filters']['text'] = array(
- '#type' => 'search',
- '#title' => $this->t('Search'),
- '#size' => 30,
- '#placeholder' => $this->t('Enter view name'),
- '#attributes' => array(
- 'class' => array('views-filter-text'),
- 'data-table' => '.views-listing-table',
- 'autocomplete' => 'off',
- 'title' => $this->t('Enter a part of the view name or description to filter by.'),
- ),
- );
-
- $list['enabled']['heading']['#markup'] = '' . $this->t('Enabled') . '
';
- $list['disabled']['heading']['#markup'] = '' . $this->t('Disabled') . '
';
- foreach (array('enabled', 'disabled') as $status) {
- $list[$status]['#type'] = 'container';
- $list[$status]['#attributes'] = array('class' => array('views-list-section', $status));
- $list[$status]['table'] = array(
- '#type' => 'table',
- '#attributes' => array(
- 'class' => array('views-listing-table'),
- ),
- '#header' => $this->buildHeader(),
- '#rows' => array(),
- );
- foreach ($entities[$status] as $entity) {
- $list[$status]['table']['#rows'][$entity->id()] = $this->buildRow($entity);
- }
- }
- // @todo Use a placeholder for the entity label if this is abstracted to
- // other entity types.
- $list['enabled']['table']['#empty'] = $this->t('There are no enabled views.');
- $list['disabled']['table']['#empty'] = $this->t('There are no disabled views.');
-
- return $list;
- }
-
- /**
- * Gets a list of displays included in the view.
- *
- * @param \Drupal\Core\Entity\EntityInterface $view
- * The view entity instance to get a list of displays for.
- *
- * @return array
- * An array of display types that this view includes.
- */
- protected function getDisplaysList(EntityInterface $view) {
- $displays = array();
- foreach ($view->get('display') as $display) {
- $definition = $this->displayManager->getDefinition($display['display_plugin']);
- if (!empty($definition['admin'])) {
- $displays[$definition['admin']] = TRUE;
- }
- }
-
- ksort($displays);
- return array_keys($displays);
- }
-
- /**
- * Gets a list of paths assigned to the view.
- *
- * @param \Drupal\Core\Entity\EntityInterface $view
- * The view entity.
- *
- * @return array
- * An array of paths for this view.
- */
- protected function getDisplayPaths(EntityInterface $view) {
- $all_paths = array();
- $executable = $view->getExecutable();
- $executable->initDisplay();
- foreach ($executable->displayHandlers as $display) {
- if ($display->hasPath()) {
- $path = $display->getPath();
- if ($view->status() && strpos($path, '%') === FALSE) {
- $all_paths[] = l('/' . $path, $path);
- }
- else {
- $all_paths[] = String::checkPlain('/' . $path);
- }
- }
- }
- return array_unique($all_paths);
- }
-
-}
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php
new file mode 100644
index 0000000..1facb3c
--- /dev/null
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php
@@ -0,0 +1,267 @@
+get('entity.manager')->getStorageController($entity_type->id()),
+ $container->get('plugin.manager.views.display')
+ );
+ }
+
+ /**
+ * Constructs a new EntityListController object.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type definition.
+ * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage.
+ * The entity storage controller class.
+ * @param \Drupal\Component\Plugin\PluginManagerInterface $display_manager
+ * The views display plugin manager to use.
+ */
+ public function __construct(EntityTypeInterface $entity_type, EntityStorageControllerInterface $storage, PluginManagerInterface $display_manager) {
+ parent::__construct($entity_type, $storage);
+
+ $this->displayManager = $display_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load() {
+ $entities = array(
+ 'enabled' => array(),
+ 'disabled' => array(),
+ );
+ foreach (parent::load() as $entity) {
+ if ($entity->status()) {
+ $entities['enabled'][] = $entity;
+ }
+ else {
+ $entities['disabled'][] = $entity;
+ }
+ }
+ return $entities;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildRow(EntityInterface $view) {
+ $row = parent::buildRow($view);
+ return array(
+ 'data' => array(
+ 'view_name' => array(
+ 'data' => array(
+ '#theme' => 'views_ui_view_info',
+ '#view' => $view,
+ '#displays' => $this->getDisplaysList($view)
+ ),
+ ),
+ 'description' => array(
+ 'data' => array(
+ '#markup' => String::checkPlain($view->get('description')),
+ ),
+ 'class' => array('views-table-filter-text-source'),
+ ),
+ 'tag' => $view->get('tag'),
+ 'path' => implode(', ', $this->getDisplayPaths($view)),
+ 'operations' => $row['operations'],
+ ),
+ 'title' => $this->t('Machine name: @name', array('@name' => $view->id())),
+ 'class' => array($view->status() ? 'views-ui-list-enabled' : 'views-ui-list-disabled'),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildHeader() {
+ return array(
+ 'view_name' => array(
+ 'data' => $this->t('View name'),
+ 'class' => array('views-ui-name'),
+ ),
+ 'description' => array(
+ 'data' => $this->t('Description'),
+ 'class' => array('views-ui-description'),
+ ),
+ 'tag' => array(
+ 'data' => $this->t('Tag'),
+ 'class' => array('views-ui-tag'),
+ ),
+ 'path' => array(
+ 'data' => $this->t('Path'),
+ 'class' => array('views-ui-path'),
+ ),
+ 'operations' => array(
+ 'data' => $this->t('Operations'),
+ 'class' => array('views-ui-operations'),
+ ),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOperations(EntityInterface $entity) {
+ $operations = parent::getOperations($entity);
+
+ if ($entity->hasLinkTemplate('clone')) {
+ $operations['clone'] = array(
+ 'title' => $this->t('Clone'),
+ 'weight' => 15,
+ ) + $entity->urlInfo('clone');
+ }
+
+ // Add AJAX functionality to enable/disable operations.
+ foreach (array('enable', 'disable') as $op) {
+ if (isset($operations[$op])) {
+ $operations[$op]['route_name'] = "views_ui.$op";
+ $operations[$op]['route_parameters'] = array('view' => $entity->id());
+
+ // Enable and disable operations should use AJAX.
+ $operations[$op]['attributes']['class'][] = 'use-ajax';
+ }
+ }
+
+ return $operations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ $entities = $this->load();
+ $list['#type'] = 'container';
+ $list['#attributes']['id'] = 'views-entity-list';
+
+ $list['#attached']['css'] = ViewFormControllerBase::getAdminCSS();
+ $list['#attached']['library'][] = 'core/drupal.ajax';
+ $list['#attached']['library'][] = 'views_ui/views_ui.listing';
+
+ $form['filters'] = array(
+ '#type' => 'container',
+ '#attributes' => array(
+ 'class' => array('table-filter', 'js-show'),
+ ),
+ );
+
+ $list['filters']['text'] = array(
+ '#type' => 'search',
+ '#title' => $this->t('Search'),
+ '#size' => 30,
+ '#placeholder' => $this->t('Enter view name'),
+ '#attributes' => array(
+ 'class' => array('views-filter-text'),
+ 'data-table' => '.views-listing-table',
+ 'autocomplete' => 'off',
+ 'title' => $this->t('Enter a part of the view name or description to filter by.'),
+ ),
+ );
+
+ $list['enabled']['heading']['#markup'] = '' . $this->t('Enabled') . '
';
+ $list['disabled']['heading']['#markup'] = '' . $this->t('Disabled') . '
';
+ foreach (array('enabled', 'disabled') as $status) {
+ $list[$status]['#type'] = 'container';
+ $list[$status]['#attributes'] = array('class' => array('views-list-section', $status));
+ $list[$status]['table'] = array(
+ '#type' => 'table',
+ '#attributes' => array(
+ 'class' => array('views-listing-table'),
+ ),
+ '#header' => $this->buildHeader(),
+ '#rows' => array(),
+ );
+ foreach ($entities[$status] as $entity) {
+ $list[$status]['table']['#rows'][$entity->id()] = $this->buildRow($entity);
+ }
+ }
+ // @todo Use a placeholder for the entity label if this is abstracted to
+ // other entity types.
+ $list['enabled']['table']['#empty'] = $this->t('There are no enabled views.');
+ $list['disabled']['table']['#empty'] = $this->t('There are no disabled views.');
+
+ return $list;
+ }
+
+ /**
+ * Gets a list of displays included in the view.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $view
+ * The view entity instance to get a list of displays for.
+ *
+ * @return array
+ * An array of display types that this view includes.
+ */
+ protected function getDisplaysList(EntityInterface $view) {
+ $displays = array();
+ foreach ($view->get('display') as $display) {
+ $definition = $this->displayManager->getDefinition($display['display_plugin']);
+ if (!empty($definition['admin'])) {
+ $displays[$definition['admin']] = TRUE;
+ }
+ }
+
+ ksort($displays);
+ return array_keys($displays);
+ }
+
+ /**
+ * Gets a list of paths assigned to the view.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $view
+ * The view entity.
+ *
+ * @return array
+ * An array of paths for this view.
+ */
+ protected function getDisplayPaths(EntityInterface $view) {
+ $all_paths = array();
+ $executable = $view->getExecutable();
+ $executable->initDisplay();
+ foreach ($executable->displayHandlers as $display) {
+ if ($display->hasPath()) {
+ $path = $display->getPath();
+ if ($view->status() && strpos($path, '%') === FALSE) {
+ $all_paths[] = l('/' . $path, $path);
+ }
+ else {
+ $all_paths[] = String::checkPlain('/' . $path);
+ }
+ }
+ }
+ return array_unique($all_paths);
+ }
+
+}
diff --git a/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewListBuilderTest.php b/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewListBuilderTest.php
deleted file mode 100644
index 99216db..0000000
--- a/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewListBuilderTest.php
+++ /dev/null
@@ -1,146 +0,0 @@
- 'Views List Builder Unit Test',
- 'description' => 'Unit tests the views list builder',
- 'group' => 'Views UI',
- );
- }
-
- /**
- * Tests the listing of displays on a views list builder.
- *
- * @see \Drupal\views_ui\ViewListBuilder::getDisplaysList()
- */
- public function testBuildRowEntityList() {
- $storage_controller = $this->getMockBuilder('Drupal\Core\Config\Entity\ConfigStorageController')
- ->disableOriginalConstructor()
- ->getMock();
- $display_manager = $this->getMockBuilder('\Drupal\views\Plugin\ViewsPluginManager')
- ->disableOriginalConstructor()
- ->getMock();
-
- $display_manager->expects($this->any())
- ->method('getDefinition')
- ->will($this->returnValueMap(array(
- array(
- 'default',
- array(
- 'id' => 'default',
- 'title' => 'Master',
- 'theme' => 'views_view',
- 'no_ui' => TRUE,
- )
- ),
- array(
- 'page',
- array(
- 'id' => 'page',
- 'title' => 'Page',
- 'uses_hook_menu' => TRUE,
- 'uses_route' => TRUE,
- 'contextual_links_locations' => array('page'),
- 'theme' => 'views_view',
- 'admin' => 'Page admin label',
- )
- ),
- array(
- 'embed',
- array(
- 'id' => 'embed',
- 'title' => 'embed',
- 'theme' => 'views_view',
- 'admin' => 'Embed admin label',
- )
- ),
- )));
-
-
- $default_display = $this->getMock('Drupal\views\Plugin\views\display\DefaultDisplay',
- array('initDisplay'),
- array(array(), 'default', $display_manager->getDefinition('default'))
- );
- $route_provider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
- $state = $this->getMock('\Drupal\Core\KeyValueStore\StateInterface');
- $page_display = $this->getMock('Drupal\views\Plugin\views\display\Page',
- array('initDisplay', 'getPath'),
- array(array(), 'default', $display_manager->getDefinition('page'), $route_provider, $state)
- );
- $page_display->expects($this->any())
- ->method('getPath')
- ->will($this->returnValue('test_page'));
-
- $embed_display = $this->getMock('Drupal\views\Plugin\views\display\Embed', array('initDisplay'),
- array(array(), 'default', $display_manager->getDefinition('embed'))
- );
-
- $values = array();
- $values['status'] = FALSE;
- $values['display']['default']['id'] = 'default';
- $values['display']['default']['display_title'] = 'Display';
- $values['display']['default']['display_plugin'] = 'default';
-
- $values['display']['page_1']['id'] = 'page_1';
- $values['display']['page_1']['display_title'] = 'Page 1';
- $values['display']['page_1']['display_plugin'] = 'page';
- $values['display']['page_1']['display_options']['path'] = 'test_page';
-
- $values['display']['embed']['id'] = 'embed';
- $values['display']['embed']['display_title'] = 'Embedded';
- $values['display']['embed']['display_plugin'] = 'embed';
-
- $display_manager->expects($this->any())
- ->method('createInstance')
- ->will($this->returnValueMap(array(
- array('default', $values['display']['default'], $default_display),
- array('page', $values['display']['page_1'], $page_display),
- array('embed', $values['display']['embed'], $embed_display),
- )));
-
- $container = new ContainerBuilder();
- $user = $this->getMock('Drupal\Core\Session\AccountInterface');
- $executable_factory = new ViewExecutableFactory($user);
- $container->set('views.executable', $executable_factory);
- $container->set('plugin.manager.views.display', $display_manager);
- \Drupal::setContainer($container);
-
- // Setup a view list builder with a mocked buildOperations method,
- // because t() is called on there.
- $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
- $view_list_builder = new TestViewListBuilder($entity_type, $storage_controller, $display_manager);
- $view_list_builder->setTranslationManager($this->getStringTranslationStub());
-
- $view = new View($values, 'view');
-
- $row = $view_list_builder->buildRow($view);
-
- $this->assertEquals(array('Embed admin label', 'Page admin label'), $row['data']['view_name']['data']['#displays'], 'Wrong displays got added to view list');
- $this->assertEquals($row['data']['path'], '/test_page', 'The path of the page display is not added.');
- }
-
-}
-
-class TestViewListBuilder extends ViewListBuilder {
-
- public function buildOperations(EntityInterface $entity) {
- return array();
- }
-
-}
diff --git a/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewListControllerTest.php b/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewListControllerTest.php
new file mode 100644
index 0000000..62a1586
--- /dev/null
+++ b/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewListControllerTest.php
@@ -0,0 +1,146 @@
+ 'Views List Controller Unit Test',
+ 'description' => 'Unit tests the views list controller',
+ 'group' => 'Views UI',
+ );
+ }
+
+ /**
+ * Tests the listing of displays on a views list.
+ *
+ * @see \Drupal\views_ui\ViewListController::getDisplaysList().
+ */
+ public function testBuildRowEntityList() {
+ $storage_controller = $this->getMockBuilder('Drupal\Core\Config\Entity\ConfigStorageController')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $display_manager = $this->getMockBuilder('\Drupal\views\Plugin\ViewsPluginManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $display_manager->expects($this->any())
+ ->method('getDefinition')
+ ->will($this->returnValueMap(array(
+ array(
+ 'default',
+ array(
+ 'id' => 'default',
+ 'title' => 'Master',
+ 'theme' => 'views_view',
+ 'no_ui' => TRUE,
+ )
+ ),
+ array(
+ 'page',
+ array(
+ 'id' => 'page',
+ 'title' => 'Page',
+ 'uses_hook_menu' => TRUE,
+ 'uses_route' => TRUE,
+ 'contextual_links_locations' => array('page'),
+ 'theme' => 'views_view',
+ 'admin' => 'Page admin label',
+ )
+ ),
+ array(
+ 'embed',
+ array(
+ 'id' => 'embed',
+ 'title' => 'embed',
+ 'theme' => 'views_view',
+ 'admin' => 'Embed admin label',
+ )
+ ),
+ )));
+
+
+ $default_display = $this->getMock('Drupal\views\Plugin\views\display\DefaultDisplay',
+ array('initDisplay'),
+ array(array(), 'default', $display_manager->getDefinition('default'))
+ );
+ $route_provider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
+ $state = $this->getMock('\Drupal\Core\KeyValueStore\StateInterface');
+ $page_display = $this->getMock('Drupal\views\Plugin\views\display\Page',
+ array('initDisplay', 'getPath'),
+ array(array(), 'default', $display_manager->getDefinition('page'), $route_provider, $state)
+ );
+ $page_display->expects($this->any())
+ ->method('getPath')
+ ->will($this->returnValue('test_page'));
+
+ $embed_display = $this->getMock('Drupal\views\Plugin\views\display\Embed', array('initDisplay'),
+ array(array(), 'default', $display_manager->getDefinition('embed'))
+ );
+
+ $values = array();
+ $values['status'] = FALSE;
+ $values['display']['default']['id'] = 'default';
+ $values['display']['default']['display_title'] = 'Display';
+ $values['display']['default']['display_plugin'] = 'default';
+
+ $values['display']['page_1']['id'] = 'page_1';
+ $values['display']['page_1']['display_title'] = 'Page 1';
+ $values['display']['page_1']['display_plugin'] = 'page';
+ $values['display']['page_1']['display_options']['path'] = 'test_page';
+
+ $values['display']['embed']['id'] = 'embed';
+ $values['display']['embed']['display_title'] = 'Embedded';
+ $values['display']['embed']['display_plugin'] = 'embed';
+
+ $display_manager->expects($this->any())
+ ->method('createInstance')
+ ->will($this->returnValueMap(array(
+ array('default', $values['display']['default'], $default_display),
+ array('page', $values['display']['page_1'], $page_display),
+ array('embed', $values['display']['embed'], $embed_display),
+ )));
+
+ $container = new ContainerBuilder();
+ $user = $this->getMock('Drupal\Core\Session\AccountInterface');
+ $executable_factory = new ViewExecutableFactory($user);
+ $container->set('views.executable', $executable_factory);
+ $container->set('plugin.manager.views.display', $display_manager);
+ \Drupal::setContainer($container);
+
+ // Setup a view list controller with a mocked buildOperations method,
+ // because t() is called on there.
+ $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
+ $view_list_controller = new TestViewListController($entity_type, $storage_controller, $display_manager);
+ $view_list_controller->setTranslationManager($this->getStringTranslationStub());
+
+ $view = new View($values, 'view');
+
+ $row = $view_list_controller->buildRow($view);
+
+ $this->assertEquals(array('Embed admin label', 'Page admin label'), $row['data']['view_name']['data']['#displays'], 'Wrong displays got added to view list');
+ $this->assertEquals($row['data']['path'], '/test_page', 'The path of the page display is not added.');
+ }
+
+}
+
+class TestViewListController extends ViewListController {
+
+ public function buildOperations(EntityInterface $entity) {
+ return array();
+ }
+
+}
diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module
index 9f25e89..7f140d3 100644
--- a/core/modules/views_ui/views_ui.module
+++ b/core/modules/views_ui/views_ui.module
@@ -75,7 +75,7 @@ function views_ui_entity_type_build(array &$entity_types) {
->setFormClass('clone', 'Drupal\views_ui\ViewCloneFormController')
->setFormClass('delete', 'Drupal\views_ui\ViewDeleteFormController')
->setFormClass('break_lock', 'Drupal\views_ui\Form\BreakLockForm')
- ->setListBuilderClass('Drupal\views_ui\ViewListBuilder')
+ ->setListClass('Drupal\views_ui\ViewListController')
->setLinkTemplate('edit-form', 'views_ui.edit')
->setLinkTemplate('edit-display-form', 'views_ui.edit_display')
->setLinkTemplate('preview-form', 'views_ui.preview')
diff --git a/core/profiles/minimal/config/block.block.stark_admin.yml b/core/profiles/minimal/config/block.block.stark_admin.yml
index 942d59c..68bee15 100644
--- a/core/profiles/minimal/config/block.block.stark_admin.yml
+++ b/core/profiles/minimal/config/block.block.stark_admin.yml
@@ -9,6 +9,7 @@ settings:
label: Administration
module: system
label_display: visible
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/minimal/config/block.block.stark_login.yml b/core/profiles/minimal/config/block.block.stark_login.yml
index 94f2477..fb1301f 100644
--- a/core/profiles/minimal/config/block.block.stark_login.yml
+++ b/core/profiles/minimal/config/block.block.stark_login.yml
@@ -9,6 +9,7 @@ settings:
label: 'User login'
module: user
label_display: visible
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/minimal/config/block.block.stark_tools.yml b/core/profiles/minimal/config/block.block.stark_tools.yml
index fb88b0e..9d53bc3 100644
--- a/core/profiles/minimal/config/block.block.stark_tools.yml
+++ b/core/profiles/minimal/config/block.block.stark_tools.yml
@@ -9,6 +9,7 @@ settings:
label: Tools
module: system
label_display: visible
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.bartik_breadcrumbs.yml b/core/profiles/standard/config/block.block.bartik_breadcrumbs.yml
index 355a3f9..b8c9eb0 100644
--- a/core/profiles/standard/config/block.block.bartik_breadcrumbs.yml
+++ b/core/profiles/standard/config/block.block.bartik_breadcrumbs.yml
@@ -9,6 +9,7 @@ settings:
label: Breadcrumbs
module: system
label_display: '0'
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.bartik_content.yml b/core/profiles/standard/config/block.block.bartik_content.yml
index 6666594..f7362e6 100644
--- a/core/profiles/standard/config/block.block.bartik_content.yml
+++ b/core/profiles/standard/config/block.block.bartik_content.yml
@@ -9,6 +9,7 @@ settings:
label: 'Main page content'
module: system
label_display: '0'
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.bartik_footer.yml b/core/profiles/standard/config/block.block.bartik_footer.yml
index 133ba67..07bdba5 100644
--- a/core/profiles/standard/config/block.block.bartik_footer.yml
+++ b/core/profiles/standard/config/block.block.bartik_footer.yml
@@ -9,6 +9,7 @@ settings:
label: 'Footer menu'
module: system
label_display: visible
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.bartik_help.yml b/core/profiles/standard/config/block.block.bartik_help.yml
index 076ee32..6ee1371 100644
--- a/core/profiles/standard/config/block.block.bartik_help.yml
+++ b/core/profiles/standard/config/block.block.bartik_help.yml
@@ -9,6 +9,7 @@ settings:
label: 'System Help'
module: system
label_display: '0'
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.bartik_login.yml b/core/profiles/standard/config/block.block.bartik_login.yml
index f654e06..235fa04 100644
--- a/core/profiles/standard/config/block.block.bartik_login.yml
+++ b/core/profiles/standard/config/block.block.bartik_login.yml
@@ -9,6 +9,7 @@ settings:
label: 'User login'
module: user
label_display: visible
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.bartik_powered.yml b/core/profiles/standard/config/block.block.bartik_powered.yml
index a2c6959..a0257a2 100644
--- a/core/profiles/standard/config/block.block.bartik_powered.yml
+++ b/core/profiles/standard/config/block.block.bartik_powered.yml
@@ -9,6 +9,7 @@ settings:
label: 'Powered by Drupal'
module: system
label_display: '0'
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.bartik_search.yml b/core/profiles/standard/config/block.block.bartik_search.yml
index aab8a85..dc39361 100644
--- a/core/profiles/standard/config/block.block.bartik_search.yml
+++ b/core/profiles/standard/config/block.block.bartik_search.yml
@@ -9,6 +9,7 @@ settings:
label: Search
module: search
label_display: visible
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.bartik_tools.yml b/core/profiles/standard/config/block.block.bartik_tools.yml
index 23cb6d9..cfe490d 100644
--- a/core/profiles/standard/config/block.block.bartik_tools.yml
+++ b/core/profiles/standard/config/block.block.bartik_tools.yml
@@ -9,6 +9,7 @@ settings:
label: Tools
module: system
label_display: visible
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.seven_breadcrumbs.yml b/core/profiles/standard/config/block.block.seven_breadcrumbs.yml
index 0a89ca3..b48f4b4 100644
--- a/core/profiles/standard/config/block.block.seven_breadcrumbs.yml
+++ b/core/profiles/standard/config/block.block.seven_breadcrumbs.yml
@@ -9,6 +9,7 @@ settings:
label: Breadcrumbs
module: system
label_display: '0'
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.seven_content.yml b/core/profiles/standard/config/block.block.seven_content.yml
index eb2fafa..1f44d0e 100644
--- a/core/profiles/standard/config/block.block.seven_content.yml
+++ b/core/profiles/standard/config/block.block.seven_content.yml
@@ -9,6 +9,7 @@ settings:
label: 'Main page content'
module: system
label_display: '0'
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.seven_help.yml b/core/profiles/standard/config/block.block.seven_help.yml
index 98f56c3..2f3121f 100644
--- a/core/profiles/standard/config/block.block.seven_help.yml
+++ b/core/profiles/standard/config/block.block.seven_help.yml
@@ -9,6 +9,7 @@ settings:
label: 'System Help'
module: system
label_display: '0'
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/profiles/standard/config/block.block.seven_login.yml b/core/profiles/standard/config/block.block.seven_login.yml
index 5bbfbf9..8eae9f4 100644
--- a/core/profiles/standard/config/block.block.seven_login.yml
+++ b/core/profiles/standard/config/block.block.seven_login.yml
@@ -9,6 +9,7 @@ settings:
label: 'User login'
module: user
label_display: visible
+ cache: -1
visibility:
path:
visibility: 0
diff --git a/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php b/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php
deleted file mode 100644
index 6e5864d..0000000
--- a/core/tests/Drupal/Tests/Core/Cache/CacheContextsTest.php
+++ /dev/null
@@ -1,96 +0,0 @@
- 'CacheContext test',
- 'description' => 'Tests cache contexts.',
- 'group' => 'Cache',
- );
- }
-
- public function testContextPlaceholdersAreReplaced() {
- $container = $this->getMockContainer();
- $container->expects($this->once())
- ->method("get")
- ->with("cache_context.foo")
- ->will($this->returnValue(new FooCacheContext()));
-
- $cache_contexts = new CacheContexts($container, $this->getContextsFixture());
-
- $new_keys = $cache_contexts->convertTokensToKeys(
- array("non-cache-context", "cache_context.foo")
- );
-
- $expected = array("non-cache-context", "bar");
- $this->assertEquals($expected, $new_keys);
- }
-
- public function testAvailableContextStrings() {
- $cache_contexts = new CacheContexts($this->getMockContainer(), $this->getContextsFixture());
- $contexts = $cache_contexts->getAll();
- $this->assertEquals(array("cache_context.foo"), $contexts);
- }
-
- public function testAvailableContextLabels() {
- $container = $this->getMockContainer();
- $container->expects($this->once())
- ->method("get")
- ->with("cache_context.foo")
- ->will($this->returnValue(new FooCacheContext()));
-
- $cache_contexts = new CacheContexts($container, $this->getContextsFixture());
- $labels = $cache_contexts->getLabels();
- $expected = array("cache_context.foo" => "Foo");
- $this->assertEquals($expected, $labels);
- }
-
- protected function getContextsFixture() {
- return array('cache_context.foo');
- }
-
- protected function getMockContainer() {
- return $this->getMockBuilder('Drupal\Core\DependencyInjection\Container')
- ->disableOriginalConstructor()
- ->getMock();
- }
-}
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php
deleted file mode 100644
index 0d9881f..0000000
--- a/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php
+++ /dev/null
@@ -1,122 +0,0 @@
- 'Entity list builder test',
- 'description' => 'Unit test of entity list builder system.',
- 'group' => 'Entity'
- );
- }
-
- /**
- * {@inheritdoc}
- */
- protected function setUp() {
- parent::setUp();
-
- $this->role = $this->getMock('Drupal\user\RoleInterface');
- $role_storage_controller = $this->getMock('Drupal\user\RoleStorageControllerInterface');
- $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
- $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
- $this->entityListBuilder = new TestEntityListBuilder($entity_type, $role_storage_controller, $module_handler);
- }
-
- /**
- * Tests that buildRow() returns a string which has been run through
- * String::checkPlain().
- *
- * @dataProvider providerTestBuildRow
- *
- * @param string $input
- * The entity label being passed into buildRow.
- * @param string $expected
- * The expected output of the label from buildRow.
- * @param string $message
- * The message to provide as output for the test.
- * @param bool $ignorewarnings
- * Whether or not to ignore PHP 5.3+ invalid multibyte sequence warnings.
- *
- * @see \Drupal\Core\Entity\EntityListBuilder::buildRow()
- */
- public function testBuildRow($input, $expected, $message, $ignorewarnings = FALSE) {
- $this->role->expects($this->any())
- ->method('label')
- ->will($this->returnValue($input));
-
- if ($ignorewarnings) {
- $built_row = @$this->entityListBuilder->buildRow($this->role);
- }
- else {
- $built_row = $this->entityListBuilder->buildRow($this->role);
- }
-
- $this->assertEquals($built_row['label'], $expected, $message);
- }
-
- /**
- * Data provider for testBuildRow().
- *
- * @see self::testBuildRow()
- * @see \Drupal\Tests\Component\Utility\StringTest::providerCheckPlain()
- *
- * @return array
- * An array containing a string, the expected return from
- * String::checkPlain, a message to be output for failures, and whether the
- * test should be processed as multibyte.
- */
- public function providerTestBuildRow() {
- $tests = array();
- // Checks that invalid multi-byte sequences are rejected.
- $tests[] = array("Foo\xC0barbaz", '', 'EntityTestListBuilder::buildRow() rejects invalid sequence "Foo\xC0barbaz"', TRUE);
- $tests[] = array("\xc2\"", '', 'EntityTestListBuilder::buildRow() rejects invalid sequence "\xc2\""', TRUE);
- $tests[] = array("Fooÿñ", "Fooÿñ", 'EntityTestListBuilder::buildRow() accepts valid sequence "Fooÿñ"');
-
- // Checks that special characters are escaped.
- $tests[] = array("