Commit 9e8a5230 authored by alexpott's avatar alexpott

Issue #2359509 by Berdir: Incorrect type safe check in...

Issue #2359509 by Berdir: Incorrect type safe check in Entity::onUpdateBundleEntity() results too many cache clears
parent 194539a7
......@@ -67,12 +67,25 @@ protected function deleteDisplays() {
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
$entity_manager = $this->entityManager();
$bundle_of = $this->getEntityType()->getBundleOf();
if (!$update) {
$this->entityManager()->onBundleCreate($this->id(), $this->getEntityType()->getBundleOf());
$entity_manager->onBundleCreate($this->id(), $bundle_of);
}
elseif ($this->getOriginalId() != $this->id()) {
$this->renameDisplays();
$this->entityManager()->onBundleRename($this->getOriginalId(), $this->id(), $this->getEntityType()->getBundleOf());
else {
// Invalidate the render cache of entities for which this entity
// is a bundle.
if ($entity_manager->hasHandler($bundle_of, 'view_builder')) {
$entity_manager->getViewBuilder($bundle_of)->resetCache();
}
// Entity bundle field definitions may depend on bundle settings.
$entity_manager->clearCachedFieldDefinitions();
if ($this->getOriginalId() != $this->id()) {
// If the entity was renamed, update the displays.
$this->renameDisplays();
$entity_manager->onBundleRename($this->getOriginalId(), $this->id(), $bundle_of);
}
}
}
......
......@@ -135,7 +135,6 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
public function __construct(array $values, $entity_type, $bundle = FALSE, $translations = array()) {
$this->entityTypeId = $entity_type;
$this->entityKeys['bundle'] = $bundle ? $bundle : $this->entityTypeId;
$this->languages = $this->languageManager()->getLanguages(LanguageInterface::STATE_ALL);
foreach ($values as $key => $value) {
// If the key matches an existing property set the value to the property
......@@ -185,6 +184,16 @@ protected function typedDataManager() {
return \Drupal::typedDataManager();
}
/**
* {@inheritdoc}
*/
protected function getLanguages() {
if (empty($this->languages)) {
$this->languages = $this->languageManager()->getLanguages(LanguageInterface::STATE_ALL);
}
return $this->languages;
}
/**
* {@inheritdoc}
*/
......@@ -278,6 +287,7 @@ public function __sleep() {
}
$this->fields = array();
$this->fieldDefinitions = NULL;
$this->languages = NULL;
$this->clearTranslationCache();
return parent::__sleep();
......@@ -454,7 +464,7 @@ public function language() {
$language = NULL;
if ($this->activeLangcode != LanguageInterface::LANGCODE_DEFAULT) {
if (!isset($this->languages[$this->activeLangcode])) {
$this->languages += $this->languageManager()->getLanguages(LanguageInterface::STATE_ALL);
$this->getLanguages();
}
$language = $this->languages[$this->activeLangcode];
}
......@@ -462,7 +472,7 @@ public function language() {
// @todo Avoid this check by getting the language from the language
// manager directly in https://www.drupal.org/node/2303877.
if (!isset($this->languages[$this->defaultLangcode])) {
$this->languages += $this->languageManager()->getLanguages(LanguageInterface::STATE_ALL);
$this->getLanguages();
}
$language = $this->languages[$this->defaultLangcode];
}
......@@ -558,6 +568,7 @@ public function getTranslation($langcode) {
else {
// If we were given a valid language and there is no translation for it,
// we return a new one.
$this->getLanguages();
if (isset($this->languages[$langcode])) {
// If the entity or the requested language is not a configured
// language, we fall back to the entity itself, since in this case it
......@@ -635,6 +646,7 @@ public function hasTranslation($langcode) {
* {@inheritdoc}
*/
public function addTranslation($langcode, array $values = array()) {
$this->getLanguages();
if (!isset($this->languages[$langcode]) || $this->hasTranslation($langcode)) {
$message = 'Invalid translation language (@langcode) specified.';
throw new \InvalidArgumentException(String::format($message, array('@langcode' => $langcode)));
......@@ -707,7 +719,7 @@ public function getTranslationLanguages($include_default = TRUE) {
}
// Now load language objects based upon translation langcodes.
return array_intersect_key($this->languages, $translations);
return array_intersect_key($this->getLanguages(), $translations);
}
/**
......
......@@ -477,7 +477,6 @@ protected function invalidateTagsOnSave($update) {
if ($update) {
// An existing entity was updated, also invalidate its unique cache tag.
$tags = Cache::mergeTags($tags, $this->getCacheTags());
$this->onUpdateBundleEntity();
}
Cache::invalidateTags($tags);
}
......@@ -503,25 +502,6 @@ protected static function invalidateTagsOnDelete(EntityTypeInterface $entity_typ
Cache::invalidateTags($tags);
}
/**
* Acts on entities of which this entity is a bundle entity type.
*/
protected function onUpdateBundleEntity() {
$bundle_of = $this->getEntityType()->getBundleOf();
if ($bundle_of !== FALSE) {
// If this entity is a bundle entity type of another entity type, and we're
// updating an existing entity, and that other entity type has a view
// builder class, then invalidate the render cache of entities for which
// this entity is a bundle.
$entity_manager = $this->entityManager();
if ($entity_manager->hasHandler($bundle_of, 'view_builder')) {
$entity_manager->getViewBuilder($bundle_of)->resetCache();
}
// Entity bundle field definitions may depend on bundle settings.
$entity_manager->clearCachedFieldDefinitions();
}
}
/**
* {@inheritdoc}
*/
......
......@@ -49,7 +49,6 @@ public function testLocks() {
$methods = get_class_methods('Drupal\comment\Entity\Comment');
unset($methods[array_search('preSave', $methods)]);
unset($methods[array_search('postSave', $methods)]);
$methods[] = 'onUpdateBundleEntity';
$methods[] = 'invalidateTagsOnSave';
$comment = $this->getMockBuilder('Drupal\comment\Entity\Comment')
->disableOriginalConstructor()
......
......@@ -792,7 +792,6 @@ public function testDeleteNothing() {
* @return \Drupal\Core\Entity\EntityInterface|\PHPUnit_Framework_MockObject_MockObject
*/
public function getMockEntity(array $values = array(), $methods = array()) {
$methods[] = 'onUpdateBundleEntity';
return $this->getMockForAbstractClass('Drupal\Core\Config\Entity\ConfigEntityBase', array($values, 'test_entity_type'), '', TRUE, TRUE, TRUE, $methods);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment