Commit 9e722833 authored by webchick's avatar webchick

Issue #2069373 by swentel, yched: Race conditions on import if CUD on...

Issue #2069373 by swentel, yched: Race conditions on import if CUD on ConfigEntity A triggers changes in ConfigEntity B.
parent e0d8e66b
......@@ -34,6 +34,14 @@ abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface
*/
public $status = TRUE;
/**
* Whether the config is being created, updated or deleted through the
* import process.
*
* @var bool
*/
private $isSyncing = FALSE;
/**
* Overrides Entity::__construct().
*/
......@@ -90,21 +98,21 @@ public function set($property_name, $value) {
}
/**
* Implements \Drupal\Core\Config\Entity\ConfigEntityInterface::enable().
* {@inheritdoc}
*/
public function enable() {
return $this->setStatus(TRUE);
}
/**
* Implements \Drupal\Core\Config\Entity\ConfigEntityInterface::disable().
* {@inheritdoc}
*/
public function disable() {
return $this->setStatus(FALSE);
}
/**
* Implements \Drupal\Core\Config\Entity\ConfigEntityInterface::setStatus().
* {@inheritdoc}
*/
public function setStatus($status) {
$this->status = (bool) $status;
......@@ -112,14 +120,28 @@ public function setStatus($status) {
}
/**
* Implements \Drupal\Core\Config\Entity\ConfigEntityInterface::status().
* {@inheritdoc}
*/
public function status() {
return !empty($this->status);
}
/**
* Overrides Entity::createDuplicate().
* {@inheritdoc}
*/
public function setSyncing($syncing) {
$this->isSyncing = $syncing;
}
/**
* {@inheritdoc}
*/
public function isSyncing() {
return $this->isSyncing;
}
/**
* {@inheritdoc}
*/
public function createDuplicate() {
$duplicate = parent::createDuplicate();
......
......@@ -59,6 +59,14 @@ public function disable();
*/
public function setStatus($status);
/**
* Sets the status of the isSyncing flag.
*
* @param bool $status
* The status of the sync flag.
*/
public function setSyncing($status);
/**
* Returns whether the configuration entity is enabled.
*
......@@ -75,6 +83,14 @@ public function setStatus($status);
*/
public function status();
/**
* Returns whether the configuration entity is created, updated or deleted
* through the import process.
*
* @return bool
*/
public function isSyncing();
/**
* Returns the value of a property.
*
......
......@@ -484,6 +484,7 @@ public function getQueryServicename() {
*/
public function importCreate($name, Config $new_config, Config $old_config) {
$entity = $this->create($new_config->get());
$entity->setSyncing(TRUE);
$entity->save();
return TRUE;
}
......@@ -504,6 +505,7 @@ public function importCreate($name, Config $new_config, Config $old_config) {
public function importUpdate($name, Config $new_config, Config $old_config) {
$id = static::getIDFromConfigName($name, $this->entityInfo['config_prefix']);
$entity = $this->load($id);
$entity->setSyncing(TRUE);
$entity->original = clone $entity;
foreach ($old_config->get() as $property => $value) {
......@@ -534,6 +536,7 @@ public function importUpdate($name, Config $new_config, Config $old_config) {
public function importDelete($name, Config $new_config, Config $old_config) {
$id = static::getIDFromConfigName($name, $this->entityInfo['config_prefix']);
$entity = $this->load($id);
$entity->setSyncing(TRUE);
$entity->delete();
return TRUE;
}
......
......@@ -170,8 +170,9 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $
entity_invoke_bundle_hook('create', 'node', $this->id());
// Unless disabled, automatically create a Body field for new node types.
if ($this->get('create_body')) {
// Create a body if the create_body property is true and we're not in
// the syncing process.
if ($this->get('create_body') && !$this->isSyncing()) {
$label = $this->get('create_body_label');
node_add_body_field($this, $label);
}
......
......@@ -78,6 +78,7 @@ public function testImportCreate() {
// Check that the content type was created.
$node_type = entity_load('node_type', $node_type_id);
$this->assertTrue($node_type, 'Import node type from staging was created.');
$this->assertFalse(field_info_instance('node', 'body', $node_type_id));
}
}
......@@ -138,6 +138,14 @@ class ViewUI implements ViewStorageInterface {
'reorder-displays' => '\Drupal\views_ui\Form\Ajax\ReorderDisplays',
);
/**
* Whether the config is being created, updated or deleted through the
* import process.
*
* @var bool
*/
private $isSyncing = FALSE;
/**
* Constructs a View UI object.
*
......@@ -187,6 +195,20 @@ public static function getDefaultAJAXMessage() {
return '<div class="message">' . t("Click on an item to edit that item's details.") . '</div>';
}
/**
* {@inheritdoc}
*/
public function setSyncing($syncing) {
$this->isSyncing = $syncing;
}
/**
* {@inheritdoc}
*/
public function isSyncing() {
return $this->isSyncing;
}
/**
* Basic submit handler applicable to all 'standard' forms.
*
......
......@@ -45,7 +45,8 @@ public function testEntityDecoration() {
// EntityInterface::isNew() is missing from the list of methods, because it
// calls id(), which breaks the ->expect($this->once()) call. Call it later.
if ($reflection_method->getName() != 'isNew') {
// EntityInterface::isSyncing() is only called during syncing process.
if ($reflection_method->getName() != 'isNew' && $reflection_method->getName() != 'isSyncing') {
if (count($reflection_method->getParameters()) == 0) {
$method_args[$reflection_method->getName()] = array();
}
......
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