Update to Drupal 8.2.0. For more information, see https://www.drupal.org/project/drupal/releases/8.2.0

This commit is contained in:
Pantheon Automation 2016-10-06 15:16:20 -07:00 committed by Greg Anderson
parent 2f563ab520
commit f1c8716f57
1732 changed files with 52334 additions and 11780 deletions

View file

@ -436,6 +436,13 @@ abstract class ContentEntityStorageBase extends EntityStorageBase implements Con
$result = [];
$args = array_slice(func_get_args(), 2);
$langcodes = array_keys($entity->getTranslationLanguages());
// Ensure that the field method is invoked as first on the current entity
// translation and then on all other translations.
$current_entity_langcode = $entity->language()->getId();
if (reset($langcodes) != $current_entity_langcode) {
$langcodes = array_diff($langcodes, [$current_entity_langcode]);
array_unshift($langcodes, $current_entity_langcode);
}
foreach ($langcodes as $langcode) {
$translation = $entity->getTranslation($langcode);
// For non translatable fields, there is only one field object instance

View file

@ -5,6 +5,7 @@ namespace Drupal\Core\Entity;
use Drupal\Core\Extension\ModuleUninstallValidatorInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\Core\Url;
/**
* Validates module uninstall readiness based on existing content entities.
@ -37,10 +38,14 @@ class ContentUninstallValidator implements ModuleUninstallValidatorInterface {
*/
public function validate($module) {
$entity_types = $this->entityManager->getDefinitions();
$reasons = array();
$reasons = [];
foreach ($entity_types as $entity_type) {
if ($module == $entity_type->getProvider() && $entity_type instanceof ContentEntityTypeInterface && $this->entityManager->getStorage($entity_type->id())->hasData()) {
$reasons[] = $this->t('There is content for the entity type: @entity_type', array('@entity_type' => $entity_type->getLabel()));
$reasons[] = $this->t('There is content for the entity type: @entity_type. <a href=":url">Remove @entity_type_plural</a>.', [
'@entity_type' => $entity_type->getLabel(),
'@entity_type_plural' => $entity_type->getPluralLabel(),
':url' => Url::fromRoute('system.prepare_modules_entity_uninstall', ['entity_type_id' => $entity_type->id()])->toString(),
]);
}
}
return $reasons;

View file

@ -273,7 +273,7 @@ class EntityController implements ContainerInjectionInterface {
* (optional) The entity, set in
* \Drupal\Core\Entity\Enhancer\EntityRouteEnhancer.
*
* @return \Drupal\Core\Entity\EntityInterface|NULL
* @return \Drupal\Core\Entity\EntityInterface|null
* The entity, if it is passed in directly or if the first parameter of the
* active route is an entity; otherwise, NULL.
*/

View file

@ -346,8 +346,8 @@ class EntityAccessControlHandler extends EntityHandlerBase implements EntityAcce
* is checked for the field definition, without any specific value
* available. Defaults to NULL.
*
* @return bool
* TRUE if access is allowed, FALSE otherwise.
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
return AccessResult::allowed();

View file

@ -10,7 +10,9 @@ use Symfony\Component\DependencyInjection\ContainerAwareTrait;
/**
* Provides a wrapper around many other services relating to entities.
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
* Deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0. We cannot
* use the deprecated PHPDoc tag because this service class is still used in
* legacy code paths. Symfony would fail test cases with deprecation warnings.
*
* @todo Enforce the deprecation of each method once
* https://www.drupal.org/node/2578361 is in.

View file

@ -482,6 +482,7 @@ class EntityType implements EntityTypeInterface {
public function setStorageClass($class) {
$this->checkStorageClass($class);
$this->handlers['storage'] = $class;
return $this;
}
/**

View file

@ -526,7 +526,9 @@ interface EntityTypeInterface extends PluginDefinitionInterface {
/**
* Gets the name of the entity type which provides bundles.
*
* @return string
* @return string|null
* The name of the entity type which provides bundles, or NULL if the entity
* type does not have a bundle entity type.
*/
public function getBundleEntityType();

View file

@ -17,13 +17,21 @@ use Symfony\Component\DependencyInjection\ContainerAwareTrait;
/**
* Manages entity type plugin definitions.
*
* Each entity type definition array is set in the entity type's
* annotation and altered by hook_entity_type_alter().
* Each entity type definition array is set in the entity type's annotation and
* altered by hook_entity_type_alter().
*
* Do not use hook_entity_type_alter() hook to add information to entity types,
* unless one of the following is true:
* - You are filling in default values.
* - You need to dynamically add information only in certain circumstances.
* - Your hook needs to run after hook_entity_type_build() implementations.
* Use hook_entity_type_build() instead in all other cases.
*
* @see \Drupal\Core\Entity\Annotation\EntityType
* @see \Drupal\Core\Entity\EntityInterface
* @see \Drupal\Core\Entity\EntityTypeInterface
* @see hook_entity_type_alter()
* @see hook_entity_type_build()
*/
class EntityTypeManager extends DefaultPluginManager implements EntityTypeManagerInterface, ContainerAwareInterface {

View file

@ -3,6 +3,7 @@
namespace Drupal\Core\Entity\Plugin\DataType\Deriver;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -32,6 +33,13 @@ class EntityDeriver implements ContainerDeriverInterface {
*/
protected $entityManager;
/**
* The bundle info service.
*
* @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
*/
protected $bundleInfoService;
/**
* Constructs an EntityDeriver object.
*
@ -40,9 +48,10 @@ class EntityDeriver implements ContainerDeriverInterface {
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
*/
public function __construct($base_plugin_id, EntityManagerInterface $entity_manager) {
public function __construct($base_plugin_id, EntityManagerInterface $entity_manager, EntityTypeBundleInfoInterface $bundle_info_service) {
$this->basePluginId = $base_plugin_id;
$this->entityManager = $entity_manager;
$this->bundleInfoService = $bundle_info_service;
}
/**
@ -51,7 +60,8 @@ class EntityDeriver implements ContainerDeriverInterface {
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static(
$base_plugin_id,
$container->get('entity.manager')
$container->get('entity.manager'),
$container->get('entity_type.bundle.info')
);
}
@ -82,7 +92,7 @@ class EntityDeriver implements ContainerDeriverInterface {
) + $base_plugin_definition;
// Incorporate the bundles as entity:$entity_type:$bundle, if any.
foreach (entity_get_bundles($entity_type_id) as $bundle => $bundle_info) {
foreach ($this->bundleInfoService->getBundleInfo($entity_type_id) as $bundle => $bundle_info) {
if ($bundle !== $entity_type_id) {
$this->derivatives[$entity_type_id . ':' . $bundle] = array(
'label' => $bundle_info['label'],

View file

@ -67,7 +67,9 @@ class EntityReference extends DataReferenceBase {
public function getTarget() {
if (!isset($this->target) && isset($this->id)) {
// If we have a valid reference, return the entity's TypedData adapter.
$entity = entity_load($this->getTargetDefinition()->getEntityTypeId(), $this->id);
$entity = \Drupal::entityTypeManager()
->getStorage($this->getTargetDefinition()->getEntityTypeId())
->load($this->id);
$this->target = isset($entity) ? $entity->getTypedData() : NULL;
}
return $this->target;

View file

@ -33,10 +33,10 @@ class ReferenceAccessConstraintValidator extends ConstraintValidator {
$referenced_entities = $existing_entity->{$value->getFieldDefinition()->getName()}->referencedEntities();
// Check permission if we are not already referencing the entity.
foreach ($referenced_entities as $ref) {
if (isset($referenced_entities[$ref->id()])) {
$check_permission = FALSE;
break;
}
if (isset($referenced_entities[$ref->id()])) {
$check_permission = FALSE;
break;
}
}
}
// We check that the current user had access to view any newly added

View file

@ -46,13 +46,6 @@ class Query extends QueryBase implements QueryInterface {
*/
protected $connection;
/**
* Stores the entity manager used by the query.
*
* @var \Drupal\Core\Entity\EntityManagerInterface
*/
protected $entityManager;
/**
* Constructs a query object.
*
@ -232,7 +225,7 @@ class Query extends QueryBase implements QueryInterface {
if ($this->range) {
$this->sqlQuery->range($this->range['start'], $this->range['length']);
}
foreach ($this->sqlGroupBy as $field) {
foreach ($this->sqlGroupBy as $field) {
$this->sqlQuery->groupBy($field);
}
foreach ($this->sqlFields as $field) {

View file

@ -23,6 +23,7 @@ use Symfony\Component\Routing\RouteCollection;
* - add-form
* - edit-form
* - delete-form
* - collection
*
* @see \Drupal\Core\Entity\Routing\AdminHtmlRouteProvider.
*
@ -95,6 +96,10 @@ class DefaultHtmlRouteProvider implements EntityRouteProviderInterface, EntityHa
$collection->add("entity.{$entity_type_id}.delete_form", $delete_route);
}
if ($collection_route = $this->getCollectionRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.collection", $collection_route);
}
return $collection;
}
@ -298,6 +303,33 @@ class DefaultHtmlRouteProvider implements EntityRouteProviderInterface, EntityHa
}
}
/**
* Gets the collection route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getCollectionRoute(EntityTypeInterface $entity_type) {
// If the entity type does not provide an admin permission, there is no way
// to control access, so we cannot provide a route in a sensible way.
if ($entity_type->hasLinkTemplate('collection') && $entity_type->hasListBuilderClass() && ($admin_permission = $entity_type->getAdminPermission())) {
$route = new Route($entity_type->getLinkTemplate('collection'));
$route
->addDefaults([
'_entity_list' => $entity_type->id(),
// @todo Improve this in https://www.drupal.org/node/2767025
'_title' => '@label entities',
'_title_arguments' => ['@label' => $entity_type->getLabel()],
])
->setRequirement('_permission', $admin_permission);
return $route;
}
}
/**
* Gets the type of the ID key for a given entity type.
*

View file

@ -526,7 +526,7 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
$all_fields = $revisioned_fields;
if ($data_fields) {
$all_fields = array_merge($revisioned_fields, $data_fields);
$query->leftJoin($this->dataTable, 'data', "(revision.$this->idKey = data.$this->idKey)");
$query->leftJoin($this->dataTable, 'data', "(revision.$this->idKey = data.$this->idKey and revision.$this->langcodeKey = data.$this->langcodeKey)");
$column_names = [];
// Some fields can have more then one columns in the data table so
// column names are needed.

View file

@ -1443,7 +1443,7 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage
*
* @param array $entity_schema
* The entity schema definition.
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface|NULL $storage_definition
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface|null $storage_definition
* (optional) If a field storage definition is specified, only indexes and
* keys involving its columns will be processed. Otherwise all defined
* entity indexes and keys will be processed.
@ -1500,7 +1500,7 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage
*
* @param array $entity_schema_data
* The entity schema data definition.
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface|NULL $storage_definition
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface|null $storage_definition
* (optional) If a field storage definition is specified, only indexes and
* keys involving its columns will be processed. Otherwise all defined
* entity indexes and keys will be processed.

View file

@ -893,9 +893,9 @@ function hook_ENTITY_TYPE_storage_load(array $entities) {
* @see hook_ENTITY_TYPE_presave()
*/
function hook_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) {
$route_match = \Drupal::routeMatch();
\Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $entity->language()->getId(), $route_match->getParameter('source_langcode'));
if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) {
$route_match = \Drupal::routeMatch();
\Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $entity->language()->getId(), $route_match->getParameter('source_langcode'));
}
}