diff --git a/core/includes/schema.inc b/core/includes/schema.inc index 6563621..600d83a 100644 --- a/core/includes/schema.inc +++ b/core/includes/schema.inc @@ -525,14 +525,17 @@ function drupal_write_record($table, &$record, $primary_keys = array()) { * The converted value. */ function drupal_schema_get_field_value(array $info, $value) { - if ($info['type'] == 'int' || $info['type'] == 'serial') { - $value = (int) $value; - } - elseif ($info['type'] == 'float') { - $value = (float) $value; - } - else { - $value = (string) $value; + // Preserve legal NULL values. + if (isset($value) || !empty($info['not null'])) { + if ($info['type'] == 'int' || $info['type'] == 'serial') { + $value = (int) $value; + } + elseif ($info['type'] == 'float') { + $value = (float) $value; + } + else { + $value = (string) $value; + } } return $value; } diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php index 2bed3f6..4a6dd4d 100644 --- a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php +++ b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php @@ -306,7 +306,7 @@ protected function buildQuery($ids, $revision_id = FALSE) { if ($this->revisionKey) { // Add all fields from the {entity_revision} table. $entity_revision_fields = drupal_map_assoc(drupal_schema_fields_sql($this->entityInfo['revision_table'])); - // The id field is provided by entity, so remove it. + // The ID field is provided by entity, so remove it. unset($entity_revision_fields[$this->idKey]); // Remove all fields from the base table that are also fields by the same @@ -319,7 +319,7 @@ protected function buildQuery($ids, $revision_id = FALSE) { } $query->fields('revision', $entity_revision_fields); - // Compare revision id of the base and revision table, if equal then this + // Compare revision ID of the base and revision table, if equal then this // is the default revision. $query->addExpression('base.' . $this->revisionKey . ' = revision.' . $this->revisionKey, 'isDefaultRevision'); } diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php index 9fb88df..0c88bd8 100644 --- a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php +++ b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php @@ -50,6 +50,13 @@ class DatabaseStorageControllerNG extends DatabaseStorageController { protected $dataTable; /** + * The table that stores revision field data if the entity supports revisions. + * + * @var string + */ + protected $revisionDataTable; + + /** * Overrides DatabaseStorageController::__construct(). */ public function __construct($entity_type, array $entity_info, Connection $database, FieldInfo $field_info) { @@ -60,6 +67,11 @@ public function __construct($entity_type, array $entity_info, Connection $databa // Check if the entity type has a dedicated table for properties. if (!empty($this->entityInfo['data_table'])) { $this->dataTable = $this->entityInfo['data_table']; + // Entity types having both revision and translation support should always + // define a revision data table. + if ($this->revisionTable && !empty($this->entityInfo['revision_data_table'])) { + $this->revisionDataTable = $this->entityInfo['revision_data_table']; + } } // Work-a-round to let load() get stdClass storage records without having to @@ -161,55 +173,6 @@ protected function buildPropertyQuery(QueryInterface $entity_query, array $value } /** - * {@inheritdoc} - */ - protected function buildQuery($ids, $revision_id = FALSE) { - $query = $this->database->select($this->entityInfo['base_table'], 'base'); - $is_revision_query = $this->revisionKey && ($revision_id || !$this->dataTable); - - $query->addTag($this->entityType . '_load_multiple'); - - if ($revision_id) { - $query->join($this->revisionTable, 'revision', "revision.{$this->idKey} = base.{$this->idKey} AND revision.{$this->revisionKey} = :revisionId", array(':revisionId' => $revision_id)); - } - elseif ($is_revision_query) { - $query->join($this->revisionTable, 'revision', "revision.{$this->revisionKey} = base.{$this->revisionKey}"); - } - - // Add fields from the {entity} table. - $entity_fields = drupal_schema_fields_sql($this->entityInfo['base_table']); - - if ($is_revision_query) { - // Add all fields from the {entity_revision} table. - $entity_revision_fields = drupal_map_assoc(drupal_schema_fields_sql($this->entityInfo['revision_table'])); - // The ID field is provided by entity, so remove it. - unset($entity_revision_fields[$this->idKey]); - - // Remove all fields from the base table that are also fields by the same - // name in the revision table. - $entity_field_keys = array_flip($entity_fields); - foreach ($entity_revision_fields as $name) { - if (isset($entity_field_keys[$name])) { - unset($entity_fields[$entity_field_keys[$name]]); - } - } - $query->fields('revision', $entity_revision_fields); - - // Compare revision ID of the base and revision table, if equal then this - // is the default revision. - $query->addExpression('base.' . $this->revisionKey . ' = revision.' . $this->revisionKey, 'isDefaultRevision'); - } - - $query->fields('base', $entity_fields); - - if ($ids) { - $query->condition("base.{$this->idKey}", $ids, 'IN'); - } - - return $query; - } - - /** * Overrides DatabaseStorageController::attachLoad(). * * Added mapping from storage records to entities. @@ -265,13 +228,13 @@ protected function attachPropertyData(array &$entities, $revision_id = FALSE) { if ($this->dataTable) { // If a revision table is available, we need all the properties of the // latest revision. Otherwise we fall back to the data table. - $table = $this->revisionTable ?: $this->dataTable; + $table = $this->revisionDataTable ?: $this->dataTable; $query = $this->database->select($table, 'data', array('fetch' => \PDO::FETCH_ASSOC)) ->fields('data') ->condition($this->idKey, array_keys($entities)) ->orderBy('data.' . $this->idKey); - if ($this->revisionTable) { + if ($this->revisionDataTable) { if ($revision_id) { $query->condition($this->revisionKey, $revision_id); } @@ -288,8 +251,8 @@ protected function attachPropertyData(array &$entities, $revision_id = FALSE) { $data = $query->execute(); $field_definition = \Drupal::entityManager()->getFieldDefinitions($this->entityType); $translations = array(); - if ($this->revisionTable) { - $data_fields = array_flip(array_diff(drupal_schema_fields_sql($this->entityInfo['revision_table']), drupal_schema_fields_sql($this->entityInfo['base_table']))); + if ($this->revisionDataTable) { + $data_fields = array_flip(array_diff(drupal_schema_fields_sql($this->entityInfo['revision_data_table']), drupal_schema_fields_sql($this->entityInfo['base_table']))); } else { $data_fields = array_flip(drupal_schema_fields_sql($this->entityInfo['data_table'])); @@ -304,11 +267,7 @@ protected function attachPropertyData(array &$entities, $revision_id = FALSE) { $translations[$id][$langcode] = TRUE; foreach ($field_definition as $name => $definition) { - // Set only translatable properties, unless we are dealing with a - // revisable entity, in which case we did not load the untranslatable - // data before. - $translatable = !empty($definition['translatable']); - if (isset($data_fields[$name]) && ($this->revisionTable || $translatable)) { + if (isset($data_fields[$name])) { $entities[$id][$name][$langcode] = $values[$name]; } } @@ -360,6 +319,9 @@ public function save(EntityInterface $entity) { if ($this->dataTable) { $this->savePropertyData($entity); } + if ($this->revisionDataTable) { + $this->savePropertyData($entity, TRUE); + } $this->resetCache(array($entity->id())); $entity->postSave($this, TRUE); $this->invokeFieldMethod('update', $entity); @@ -370,15 +332,19 @@ public function save(EntityInterface $entity) { } } else { + $entity->enforceIsNew(); $return = drupal_write_record($this->entityInfo['base_table'], $record); - $entity->{$this->idKey}->value = $record->{$this->idKey}; + $entity->{$this->idKey}->value = (string) $record->{$this->idKey}; if ($this->revisionKey) { + $entity->setNewRevision(); $record->{$this->revisionKey} = $this->saveRevision($entity); } - $entity->{$this->idKey}->value = $record->{$this->idKey}; if ($this->dataTable) { $this->savePropertyData($entity); } + if ($this->revisionDataTable) { + $this->savePropertyData($entity, TRUE); + } // Reset general caches, but keep caches specific to certain entities. $this->resetCache(array()); @@ -413,53 +379,34 @@ public function save(EntityInterface $entity) { * The revision id. */ protected function saveRevision(EntityInterface $entity) { - $return = $entity->id(); - $default_langcode = $entity->getUntranslated()->language()->id; - - if (!$entity->isNewRevision()) { - // Delete to handle removed values. - $this->database->delete($this->revisionTable) - ->condition($this->idKey, $entity->id()) - ->condition($this->revisionKey, $entity->getRevisionId()) - ->execute(); - } + $record = $this->mapToStorageRecord($entity, 'revision_table'); - $languages = $this->dataTable ? $entity->getTranslationLanguages() : array($default_langcode => $entity->language()); - foreach ($languages as $langcode => $language) { - $translation = $entity->getTranslation($langcode); - $record = $this->mapToRevisionStorageRecord($translation); - $record->langcode = $langcode; - $record->default_langcode = $langcode == $default_langcode; - - // When saving a new revision, set any existing revision ID to NULL so as - // to ensure that a new revision will actually be created. - if ($entity->isNewRevision() && isset($record->{$this->revisionKey})) { - $record->{$this->revisionKey} = NULL; - } + // When saving a new revision, set any existing revision ID to NULL so as + // to ensure that a new revision will actually be created. + if ($entity->isNewRevision() && isset($record->{$this->revisionKey})) { + $record->{$this->revisionKey} = NULL; + } - $entity->preSaveRevision($this, $record); + $entity->preSaveRevision($this, $record); - if ($entity->isNewRevision()) { - drupal_write_record($this->revisionTable, $record); - if ($entity->isDefaultRevision()) { - $this->database->update($this->entityInfo['base_table']) - ->fields(array($this->revisionKey => $record->{$this->revisionKey})) - ->condition($this->idKey, $record->{$this->idKey}) - ->execute(); - } - $entity->setNewRevision(FALSE); - } - else { - // @todo Use multiple insertions to improve performance. - drupal_write_record($this->revisionTable, $record); + if ($entity->isNewRevision()) { + drupal_write_record($this->revisionTable, $record); + if ($entity->isDefaultRevision()) { + $this->database->update($this->entityInfo['base_table']) + ->fields(array($this->revisionKey => $record->{$this->revisionKey})) + ->condition($this->idKey, $record->{$this->idKey}) + ->execute(); } - - // Make sure to update the new revision key for the entity. - $entity->{$this->revisionKey}->value = $record->{$this->revisionKey}; - $return = $record->{$this->revisionKey}; + $entity->setNewRevision(FALSE); } + else { + drupal_write_record($this->revisionTable, $record, array($this->revisionKey)); + } + + // Make sure to update the new revision key for the entity. + $entity->{$this->revisionKey}->value = $record->{$this->revisionKey}; - return $return; + return $record->{$this->revisionKey}; } /** @@ -468,16 +415,24 @@ protected function saveRevision(EntityInterface $entity) { * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object. */ - protected function savePropertyData(EntityInterface $entity) { - // Delete and insert to handle removed values. - $this->database->delete($this->dataTable) - ->condition($this->idKey, $entity->id()) - ->execute(); + protected function savePropertyData(EntityInterface $entity, $revision = FALSE) { + $table_key = $revision ? 'revision_data_table' : 'data_table'; + $table_name = $revision ? $this->revisionDataTable : $this->dataTable; + + if (!$revision || !$entity->isNewRevision()) { + $key = $revision ? $this->revisionKey : $this->idKey; + $value = $revision ? $entity->getRevisionId() : $entity->id(); + // Delete and insert to handle removed values. + $this->database->delete($table_name) + ->condition($key, $value) + ->execute(); + } - $query = $this->database->insert($this->dataTable); + $query = $this->database->insert($table_name); foreach ($entity->getTranslationLanguages() as $langcode => $language) { - $record = $this->mapToDataStorageRecord($entity, $langcode); + $translation = $entity->getTranslation($langcode); + $record = $this->mapToDataStorageRecord($translation, $table_key); $values = (array) $record; $query ->fields(array_keys($values)) @@ -488,70 +443,52 @@ protected function savePropertyData(EntityInterface $entity) { } /** - * Maps from an entity object to the storage record of the base table. + * Maps from an entity object to the storage record. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object. + * @param string $table_key + * (optional) The entity key identifying the target table. Defaults to + * 'base_table'. * * @return \stdClass * The record to store. */ - protected function mapToStorageRecord(EntityInterface $entity) { - $record = new \stdClass(); - foreach (drupal_schema_fields_sql($this->entityInfo['base_table']) as $name) { - $record->$name = $entity->$name->value; - } - return $record; - } - - /** - * Maps from an entity object to the storage record of the revision table. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity object. - * - * @return \stdClass - * The record to store. - */ - protected function mapToRevisionStorageRecord(EntityInterface $entity) { + protected function mapToStorageRecord(EntityInterface $entity, $table_key = 'base_table') { $record = new \stdClass(); $definitions = $entity->getPropertyDefinitions(); - foreach (drupal_schema_fields_sql($this->entityInfo['revision_table']) as $name) { - if (isset($definitions[$name]) && isset($entity->$name->value)) { - $record->$name = $entity->$name->value; + $schema = drupal_get_schema($this->entityInfo[$table_key]); + $is_new = $entity->isNew(); + + foreach (drupal_schema_fields_sql($this->entityInfo[$table_key]) as $name) { + $info = $schema['fields'][$name]; + $value = isset($definitions[$name]) && isset($entity->$name->value) ? $entity->$name->value : NULL; + // If we are creating a new entity, we must not populate the record with + // NULL values otherwise defaults would not be applied. + if (isset($value) || !$is_new) { + $record->$name = drupal_schema_get_field_value($info, $value); } } + return $record; } /** - * Maps from an entity object to the storage record of the data table. + * Maps from an entity object to the storage record of the field date. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object. - * @param $langcode - * The language code of the translation to get. + * @param string $table_key + * (optional) The entity key identifying the target table. Defaults to + * 'data_table'. * * @return \stdClass * The record to store. */ - protected function mapToDataStorageRecord(EntityInterface $entity, $langcode) { - $default_langcode = $entity->getUntranslated()->language()->id; - // Don't use strict mode, this way there's no need to do checks here, as - // non-translatable properties are replicated for each language. - $translation = $entity->getTranslation($langcode); - $definitions = $translation->getPropertyDefinitions(); - $schema = drupal_get_schema($this->entityInfo['data_table']); - - $record = new \stdClass(); - foreach (drupal_schema_fields_sql($this->entityInfo['data_table']) as $name) { - $info = $schema['fields'][$name]; - $value = isset($definitions[$name]) && isset($translation->$name->value) ? $translation->$name->value : NULL; - $record->$name = drupal_schema_get_field_value($info, $value); - } - $record->langcode = $langcode; - $record->default_langcode = intval($default_langcode == $langcode); - + protected function mapToDataStorageRecord(EntityInterface $entity, $table_key = 'data_table') { + $record = $this->mapToStorageRecord($entity, $table_key); + $record->langcode = $entity->language()->id; + $record->default_langcode = intval($record->langcode == $entity->getUntranslated()->language()->id); return $record; } @@ -590,6 +527,12 @@ public function delete(array $entities) { ->execute(); } + if ($this->revisionDataTable) { + $this->database->delete($this->revisionDataTable) + ->condition($this->idKey, $ids) + ->execute(); + } + // Reset the cache as soon as the changes have been applied. $this->resetCache($ids); diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Tests/Views/IntegrationTest.php b/core/modules/aggregator/lib/Drupal/aggregator/Tests/Views/IntegrationTest.php index 77393d6..b59c785 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Tests/Views/IntegrationTest.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/Views/IntegrationTest.php @@ -76,6 +76,7 @@ public function testAggregatorItemView() { // Add a image to ensure that the sanitizing can be tested below. $values['author'] = $this->randomName() . '"'; $values['link'] = 'http://drupal.org/node/' . mt_rand(1000, 10000); + $values['guid'] = $this->randomString(); $aggregator_item = $this->itemStorageController->create($values); $aggregator_item->save(); diff --git a/core/modules/editor/lib/Drupal/editor/Tests/EditorFileUsageTest.php b/core/modules/editor/lib/Drupal/editor/Tests/EditorFileUsageTest.php index 97715b5..56fea49 100644 --- a/core/modules/editor/lib/Drupal/editor/Tests/EditorFileUsageTest.php +++ b/core/modules/editor/lib/Drupal/editor/Tests/EditorFileUsageTest.php @@ -31,8 +31,14 @@ public static function getInfo() { function setUp() { parent::setUp(); - $this->installSchema('node', array('node', 'node_access', 'node_field_data', 'node_field_revision')); - $this->installSchema('file', array('file_managed', 'file_usage')); + $this->installSchema('system', 'url_alias'); + $this->installSchema('node', 'node'); + $this->installSchema('node', 'node_revision'); + $this->installSchema('node', 'node_access'); + $this->installSchema('node', 'node_field_data'); + $this->installSchema('node', 'node_field_revision'); + $this->installSchema('file', 'file_managed'); + $this->installSchema('file', 'file_usage'); // Add text formats. $filtered_html_format = entity_create('filter_format', array( diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/ApiDataTest.php b/core/modules/field/lib/Drupal/field/Tests/Views/ApiDataTest.php index 1f60380..ad9963d 100644 --- a/core/modules/field/lib/Drupal/field/Tests/Views/ApiDataTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/Views/ApiDataTest.php @@ -71,7 +71,7 @@ function testViewsData() { $this->assertTrue(isset($data[$revision_table])); // The node field should join against node. $this->assertTrue(isset($data[$current_table]['table']['join']['node'])); - $this->assertTrue(isset($data[$revision_table]['table']['join']['node_field_revision'])); + $this->assertTrue(isset($data[$revision_table]['table']['join']['node_revision'])); $expected_join = array( 'left_field' => 'nid', @@ -88,7 +88,7 @@ function testViewsData() { array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), ), ); - $this->assertEqual($expected_join, $data[$revision_table]['table']['join']['node_field_revision']); + $this->assertEqual($expected_join, $data[$revision_table]['table']['join']['node_revision']); } } diff --git a/core/modules/node/config/views.view.content.yml b/core/modules/node/config/views.view.content.yml index 487b04b..efa9084 100644 --- a/core/modules/node/config/views.view.content.yml +++ b/core/modules/node/config/views.view.content.yml @@ -422,7 +422,7 @@ display: provider: views langcode: id: langcode - table: node + table: node_revision field: langcode operator: in value: { } diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php index 8367e16..b31228e 100644 --- a/core/modules/node/lib/Drupal/node/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Entity/Node.php @@ -36,7 +36,8 @@ * }, * base_table = "node", * data_table = "node_field_data", - * revision_table = "node_field_revision", + * revision_table = "node_revision", + * revision_data_table = "node_field_revision", * uri_callback = "node_uri", * fieldable = TRUE, * translatable = TRUE, diff --git a/core/modules/node/lib/Drupal/node/NodeStorageController.php b/core/modules/node/lib/Drupal/node/NodeStorageController.php index 1360af3..1e4d30d 100644 --- a/core/modules/node/lib/Drupal/node/NodeStorageController.php +++ b/core/modules/node/lib/Drupal/node/NodeStorageController.php @@ -73,9 +73,9 @@ protected function attachLoad(&$queried_entities, $load_revision = FALSE) { /** * {@inheritdoc} */ - protected function mapToDataStorageRecord(EntityInterface $entity, $langcode) { + protected function mapToDataStorageRecord(EntityInterface $entity, $table_name = 'data_table') { // @todo Remove this once comment is a regular entity field. - $record = parent::mapToDataStorageRecord($entity, $langcode); + $record = parent::mapToDataStorageRecord($entity, $table_name); $record->comment = isset($record->comment) ? intval($record->comment) : 0; return $record; } diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/argument/UidRevision.php b/core/modules/node/lib/Drupal/node/Plugin/views/argument/UidRevision.php index e32e8ac..048e1f7 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/argument/UidRevision.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/argument/UidRevision.php @@ -21,7 +21,7 @@ class UidRevision extends Uid { public function query($group_by = FALSE) { $this->ensureMyTable(); $placeholder = $this->placeholder(); - $this->query->addWhereExpression(0, "$this->tableAlias.revision_uid = $placeholder OR ((SELECT COUNT(DISTINCT vid) FROM {node_field_revision} nfr WHERE nfr.revision_uid = $placeholder AND nfr.nid = $this->tableAlias.nid) > 0)", array($placeholder => $this->argument)); + $this->query->addWhereExpression(0, "$this->tableAlias.revision_uid = $placeholder OR ((SELECT COUNT(DISTINCT vid) FROM {node_revision} nr WHERE nfr.revision_uid = $placeholder AND nr.nid = $this->tableAlias.nid) > 0)", array($placeholder => $this->argument)); } } diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/argument/Vid.php b/core/modules/node/lib/Drupal/node/Plugin/views/argument/Vid.php index f09e2a8..225982e 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/argument/Vid.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/argument/Vid.php @@ -57,7 +57,7 @@ public static function create(ContainerInterface $container, array $configuratio public function titleQuery() { $titles = array(); - $results = $this->database->query('SELECT npr.vid, npr.nid, npr.title FROM {node_field_revision} npr WHERE npr.vid IN (:vids)', array(':vids' => $this->value))->fetchAllAssoc('vid', PDO::FETCH_ASSOC); + $results = $this->database->query('SELECT nr.vid, nr.nid, npr.title FROM {node_revision} nr WHERE nr.vid IN (:vids)', array(':vids' => $this->value))->fetchAllAssoc('vid', PDO::FETCH_ASSOC); $nids = array(); foreach ($results as $result) { $nids[] = $result['nid']; diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/field/RevisionLink.php b/core/modules/node/lib/Drupal/node/Plugin/views/field/RevisionLink.php index 8b3d3d7..0bc8d15 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/field/RevisionLink.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/field/RevisionLink.php @@ -28,7 +28,7 @@ class RevisionLink extends Link { public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); - $this->additional_fields['node_vid'] = array('table' => 'node_field_revision', 'field' => 'vid'); + $this->additional_fields['node_vid'] = array('table' => 'node_revision', 'field' => 'vid'); } public function access() { diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/filter/UidRevision.php b/core/modules/node/lib/Drupal/node/Plugin/views/filter/UidRevision.php index cf715fe..b0ceabf 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/filter/UidRevision.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/filter/UidRevision.php @@ -27,7 +27,7 @@ public function query($group_by = FALSE) { $args = array_values($this->value); $this->query->addWhereExpression($this->options['group'], "$this->tableAlias.uid IN($placeholder) OR - ((SELECT COUNT(DISTINCT vid) FROM {node_field_revision} nfr WHERE nfr.revision_uid IN ($placeholder) AND nfr.nid = $this->tableAlias.nid) > 0)", array($placeholder => $args), + ((SELECT COUNT(DISTINCT vid) FROM {node_revision} nr WHERE nr.revision_uid IN ($placeholder) AND nr.nid = $this->tableAlias.nid) > 0)", array($placeholder => $args), $args); } diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/NodeRevision.php b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/NodeRevision.php index 33f5cf0..1346599 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/NodeRevision.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/NodeRevision.php @@ -20,7 +20,7 @@ * * @ViewsWizard( * id = "node_revision", - * base_table = "node_field_revision", + * base_table = "node_revision", * title = @Translation("Content revisions") * ) */ @@ -36,7 +36,7 @@ class NodeRevision extends WizardPluginBase { */ protected $pathField = array( 'id' => 'vid', - 'table' => 'node_field_revision', + 'table' => 'node_revision', 'field' => 'vid', 'exclude' => TRUE, 'alter' => array( @@ -97,7 +97,7 @@ protected function defaultDisplayOptions() { /* Field: Content revision: Created date */ $display_options['fields']['timestamp']['id'] = 'timestamp'; - $display_options['fields']['timestamp']['table'] = 'node_field_revision'; + $display_options['fields']['timestamp']['table'] = 'node_revision'; $display_options['fields']['timestamp']['field'] = 'timestamp'; $display_options['fields']['timestamp']['provider'] = 'node'; $display_options['fields']['timestamp']['alter']['alter_text'] = 0; diff --git a/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php b/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php index 4718c85..1d9a2e5 100644 --- a/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php @@ -26,7 +26,10 @@ public static function getInfo() { public function setUp() { parent::setUp(); - $this->installSchema('node', array('node', 'node_field_data', 'node_field_revision')); + $this->installSchema('node', 'node'); + $this->installSchema('node', 'node_revision'); + $this->installSchema('node', 'node_field_data'); + $this->installSchema('node', 'node_field_revision'); } /** diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php index e33d6a7..13d8ffd 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php @@ -32,6 +32,7 @@ public static function getInfo() { public function setUp() { parent::setUp(); $this->installSchema('node', 'node'); + $this->installSchema('node', 'node_revision'); $this->installSchema('node', 'node_field_data'); $this->installSchema('node', 'node_field_revision'); $this->installSchema('user', array('users')); diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php index 13e48d1..abc6668 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php @@ -134,14 +134,14 @@ function testRevisions() { '%title' => $nodes[1]->getTitle(), )), 'Revision deleted.'); - $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid and vid = :vid', + $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', array(':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()))->fetchField() == 0, 'Revision not found.'); // Set the revision timestamp to an older date to make sure that the // confirmation message correctly displays the stored revision date. $old_revision_date = REQUEST_TIME - 86400; - db_update('node_field_revision') + db_update('node_revision') ->condition('vid', $nodes[2]->getRevisionId()) ->fields(array( 'revision_timestamp' => $old_revision_date, diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php index ff31662..bcb62fc 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php @@ -114,12 +114,12 @@ function testRevisions() { $this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($nodes[1]->getRevisionCreationTime()), '@type' => 'Basic page', '%title' => $nodes[1]->label())), 'Revision deleted.'); - $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid and vid = :vid', array(':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()))->fetchField() == 0, 'Revision not found.'); + $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', array(':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()))->fetchField() == 0, 'Revision not found.'); // Set the revision timestamp to an older date to make sure that the // confirmation message correctly displays the stored revision date. $old_revision_date = REQUEST_TIME - 86400; - db_update('node_field_revision') + db_update('node_revision') ->condition('vid', $nodes[2]->getRevisionId()) ->fields(array( 'revision_timestamp' => $old_revision_date, diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php index 2d3efe8..4495c17 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php @@ -34,7 +34,10 @@ public static function getInfo() { */ public function setUp() { parent::setUp(); - $this->installSchema('node', array('node', 'node_field_data', 'node_field_revision')); + $this->installSchema('node', 'node'); + $this->installSchema('node', 'node_revision'); + $this->installSchema('node', 'node_field_data'); + $this->installSchema('node', 'node_field_revision'); // Create a node type for testing. $type = entity_create('node_type', array('type' => 'page', 'name' => 'page')); diff --git a/core/modules/node/lib/Drupal/node/Tests/Views/RevisionRelationships.php b/core/modules/node/lib/Drupal/node/Tests/Views/RevisionRelationships.php index edb40d0..f643b65 100644 --- a/core/modules/node/lib/Drupal/node/Tests/Views/RevisionRelationships.php +++ b/core/modules/node/lib/Drupal/node/Tests/Views/RevisionRelationships.php @@ -53,8 +53,8 @@ public function testNodeRevisionRelationship() { $node_revision->save(); $column_map = array( 'vid' => 'vid', - 'node_field_revision_nid' => 'node_field_revision_nid', - 'node_node_field_revision_nid' => 'node_node_field_revision_nid', + 'node_revision_nid' => 'node_revision_nid', + 'node_node_revision_nid' => 'node_node_revision_nid', ); // Here should be two rows. @@ -63,13 +63,13 @@ public function testNodeRevisionRelationship() { $resultset_nid = array( array( 'vid' => '1', - 'node_field_revision_nid' => '1', - 'node_node_field_revision_nid' => '1', + 'node_revision_nid' => '1', + 'node_node_revision_nid' => '1', ), array( 'vid' => '2', - 'node_field_revision_nid' => '1', - 'node_node_field_revision_nid' => '1', + 'node_revision_nid' => '1', + 'node_node_revision_nid' => '1', ), ); $this->assertIdenticalResultset($view_nid, $resultset_nid, $column_map); @@ -80,8 +80,8 @@ public function testNodeRevisionRelationship() { $resultset_vid = array( array( 'vid' => '2', - 'node_field_revision_nid' => '1', - 'node_node_field_revision_nid' => '1', + 'node_revision_nid' => '1', + 'node_node_revision_nid' => '1', ), ); $this->assertIdenticalResultset($view_vid, $resultset_vid, $column_map); diff --git a/core/modules/node/node.install b/core/modules/node/node.install index 3f5c370..b8896d0 100644 --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -43,13 +43,6 @@ function node_schema() { 'not null' => TRUE, 'default' => '', ), - 'langcode' => array( - 'description' => 'The {language}.langcode of this node.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), // @todo Remove the following columns when removing the legacy Content // Translation module. See http://drupal.org/node/1952062. 'tnid' => array( @@ -77,20 +70,80 @@ function node_schema() { ), 'foreign keys' => array( 'node_revision' => array( - 'table' => 'node_field_revision', + 'table' => 'node_revision', 'columns' => array('vid' => 'vid'), ), ), 'primary key' => array('nid'), ); + $schema['node_revision'] = array( + 'description' => 'Stores information about each saved version of a {node}.', + 'fields' => array( + 'nid' => array( + 'description' => 'The {node} this version belongs to.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'vid' => array( + 'description' => 'The primary identifier for this version.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'revision_uid' => array( + 'description' => 'The {users}.uid that created this version.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'log' => array( + 'description' => 'The log entry explaining the changes in this version.', + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'revision_timestamp' => array( + 'description' => 'The Unix timestamp when the version was created.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'langcode' => array( + 'description' => 'The {language}.langcode of this version.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + ), + 'indexes' => array( + 'nid' => array('nid'), + 'revision_uid' => array('revision_uid'), + 'node_langcode' => array('langcode'), + ), + 'foreign keys' => array( + 'versioned_node' => array( + 'table' => 'node', + 'columns' => array('nid' => 'nid'), + ), + 'version_author' => array( + 'table' => 'users', + 'columns' => array('revision_uid' => 'uid'), + ), + ), + 'primary key' => array('vid'), + ); + // Node field storage. $schema['node_field_data'] = array( - 'description' => 'Base table for node properties.', + 'description' => 'Data table for node base fields.', 'fields' => array( 'nid' => array( 'description' => 'The primary identifier for a node.', - 'type' => 'serial', + 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, ), @@ -180,7 +233,6 @@ function node_schema() { 'node_status_type' => array('status', 'type', 'nid'), 'node_title_type' => array('title', array('type', 4)), 'node_type' => array(array('type', 4)), - 'nid' => array('nid'), 'vid' => array('vid'), 'uid' => array('uid'), ), @@ -194,11 +246,11 @@ function node_schema() { 'columns' => array('uid' => 'uid'), ), ), - 'primary key' => array('nid', 'vid', 'langcode'), + 'primary key' => array('nid', 'langcode'), ); $schema['node_field_revision'] = array( - 'description' => 'Stores information about each saved version of a {node}.', + 'description' => 'Revision table for node base fields.', 'fields' => array( 'nid' => array( 'description' => 'The {node} this version belongs to.', @@ -208,7 +260,7 @@ function node_schema() { ), 'vid' => array( 'description' => 'The primary identifier for this version.', - 'type' => 'serial', + 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, ), @@ -225,25 +277,6 @@ function node_schema() { 'not null' => TRUE, 'default' => 1, ), - 'log' => array( - 'description' => 'The log entry explaining the changes in this version.', - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'big', - ), - 'revision_timestamp' => array( - 'description' => 'The Unix timestamp when the version was created.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'revision_uid' => array( - 'description' => 'The {users}.uid that created this version.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), 'title' => array( 'description' => 'The title of this version, always treated as non-markup plain text.', 'type' => 'varchar', @@ -296,10 +329,7 @@ function node_schema() { ), ), 'indexes' => array( - 'nid' => array('nid'), 'uid' => array('uid'), - 'revision_uid' => array('revision_uid'), - 'vid' => array('vid'), 'node_default_langcode' => array('default_langcode'), 'node_langcode' => array('langcode'), ), @@ -308,12 +338,12 @@ function node_schema() { 'table' => 'node', 'columns' => array('nid' => 'nid'), ), - 'version_author' => array( + 'node_author' => array( 'table' => 'users', 'columns' => array('uid' => 'uid'), ), ), - 'primary key' => array('nid', 'vid', 'langcode'), + 'primary key' => array('vid', 'langcode'), ); $schema['node_access'] = array( @@ -750,12 +780,13 @@ function node_update_8015() { function _node_update_8016_schema() { $schema = array(); + // Node field storage. $schema['node_field_data'] = array( - 'description' => 'Base table for node properties.', + 'description' => 'Data table for node base fields.', 'fields' => array( 'nid' => array( 'description' => 'The primary identifier for a node.', - 'type' => 'serial', + 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, ), @@ -839,11 +870,12 @@ function _node_update_8016_schema() { 'indexes' => array( 'node_changed' => array('changed'), 'node_created' => array('created'), + 'node_default_langcode' => array('default_langcode'), + 'node_langcode' => array('langcode'), 'node_frontpage' => array('promote', 'status', 'sticky', 'created'), 'node_status_type' => array('status', 'type', 'nid'), 'node_title_type' => array('title', array('type', 4)), 'node_type' => array(array('type', 4)), - 'nid' => array('nid'), 'vid' => array('vid'), 'uid' => array('uid'), ), @@ -857,11 +889,11 @@ function _node_update_8016_schema() { 'columns' => array('uid' => 'uid'), ), ), - 'primary key' => array('nid', 'vid', 'langcode'), + 'primary key' => array('nid', 'langcode'), ); $schema['node_field_revision'] = array( - 'description' => 'Stores information about each saved version of a {node}.', + 'description' => 'Revision table for node base fields.', 'fields' => array( 'nid' => array( 'description' => 'The {node} this version belongs to.', @@ -871,7 +903,7 @@ function _node_update_8016_schema() { ), 'vid' => array( 'description' => 'The primary identifier for this version.', - 'type' => 'serial', + 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, ), @@ -888,25 +920,6 @@ function _node_update_8016_schema() { 'not null' => TRUE, 'default' => 1, ), - 'log' => array( - 'description' => 'The log entry explaining the changes in this version.', - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'big', - ), - 'revision_timestamp' => array( - 'description' => 'The Unix timestamp when the version was created.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'revision_uid' => array( - 'description' => 'The {users}.uid that created this version.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), 'title' => array( 'description' => 'The title of this version, always treated as non-markup plain text.', 'type' => 'varchar', @@ -959,34 +972,62 @@ function _node_update_8016_schema() { ), ), 'indexes' => array( - 'nid' => array('nid'), 'uid' => array('uid'), - 'revision_uid' => array('revision_uid'), - 'vid' => array('vid'), + 'node_default_langcode' => array('default_langcode'), + 'node_langcode' => array('langcode'), ), 'foreign keys' => array( 'versioned_node' => array( 'table' => 'node', 'columns' => array('nid' => 'nid'), ), - 'version_author' => array( + 'node_author' => array( 'table' => 'users', 'columns' => array('uid' => 'uid'), ), ), - 'primary key' => array('nid', 'vid', 'langcode'), + 'primary key' => array('vid', 'langcode'), ); return $schema; } /** - * Upgrade node schema to the standard entity SQL schema: create new tables. + * Upgrade node schema to the standard entity SQL schema: prepare schema. */ function node_update_8016() { foreach (_node_update_8016_schema() as $table => $table_schema) { db_create_table($table, $table_schema); } + + $spec = array( + 'description' => 'The {language}.langcode of this version.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ); + $keys_new = array('indexes' => array('node_langcode' => array('langcode'))); + db_add_field('node_revision', 'langcode', $spec, $keys_new); + + $spec = array( + 'description' => 'The Unix timestamp when the version was created.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ); + db_change_field('node_revision', 'timestamp', 'revision_timestamp', $spec); + + db_drop_index('node_revision', 'uid'); + $spec = array( + 'description' => 'The {users}.uid that created this version.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ); + db_change_field('node_revision', 'uid', 'revision_uid', $spec); + db_add_index('node_revision', 'revision_uid', array('revision_uid')); } /** @@ -1002,10 +1043,11 @@ function node_update_8017(&$sandbox) { // Prepare the new records. $queries = array(); $schema = _node_update_8016_schema(); - $result = db_query_range('SELECT nr.*, nr.timestamp AS revision_timestamp, nr.uid as revision_uid, 1 AS default_langcode, n.langcode, n.vid = nr.vid AS default_revision, n.uid, n.changed, n.created, n.type FROM {node_revision} nr JOIN {node} n ON nr.nid = n.nid ORDER BY nr.nid ASC, nr.vid ASC', $sandbox['progress'], 50); + $result = db_query_range('SELECT nr.*, nr.revision_timestamp, nr.revision_uid, 1 AS default_langcode, n.langcode, n.vid = nr.vid AS default_revision, n.uid, n.changed, n.created, n.type FROM {node_revision} nr JOIN {node} n ON nr.nid = n.nid ORDER BY nr.nid ASC, nr.vid ASC', $sandbox['progress'], 50); foreach ($result as $row) { $sandbox['progress']++; + foreach ($schema as $table => $table_schema) { // We need to store the data table record only when dealing with the // default revision. @@ -1023,6 +1065,11 @@ function node_update_8017(&$sandbox) { $queries[$table]->values($record); } } + + // Populate the langcode column with the same value for each revision as we + // have no other data available. + $args = array('langcode' => $row->langcode, 'vid' => $row->vid); + db_query('UPDATE {node_revision} SET langcode = :langcode WHERE vid = :vid', $args); } // Store the new records. @@ -1041,10 +1088,14 @@ function node_update_8018() { foreach ($indexes as $index) { db_drop_index('node', $index); } - $fields = array('title', 'uid', 'status', 'created', 'changed', 'comment', 'promote', 'sticky'); + $fields = array('title', 'uid', 'status', 'created', 'changed', 'comment', 'promote', 'sticky', 'langcode'); foreach ($fields as $field) { db_drop_field('node', $field); } + $fields = array('title', 'status', 'comment', 'promote', 'sticky'); + foreach ($fields as $field) { + db_drop_field('node_revision', $field); + } } /** diff --git a/core/modules/node/node.module b/core/modules/node/node.module index e1d2b63..578244f 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -1115,7 +1115,7 @@ function node_last_changed($nid, $langcode = NULL) { */ function node_revision_list(EntityInterface $node) { $revisions = array(); - $result = db_query('SELECT nfr.vid, nfr.title, nfr.log, nfr.revision_uid AS uid, n.vid AS current_vid, nfr.revision_timestamp, u.name FROM {node_field_revision} nfr LEFT JOIN {node} n ON n.vid = nfr.vid INNER JOIN {users} u ON u.uid = nfr.revision_uid WHERE nfr.nid = :nid AND nfr.default_langcode = 1 ORDER BY nfr.vid DESC', array(':nid' => $node->id())); + $result = db_query('SELECT nr.vid, nfr.title, nr.log, nr.revision_uid AS uid, n.vid AS current_vid, nr.revision_timestamp, u.name FROM {node_field_revision} nfr JOIN {node_revision} nr ON nr.vid = nfr.vid LEFT JOIN {node} n ON n.vid = nfr.vid INNER JOIN {users} u ON u.uid = nr.revision_uid WHERE nfr.nid = :nid AND nfr.default_langcode = 1 ORDER BY nfr.vid DESC', array(':nid' => $node->id())); foreach ($result as $revision) { $revisions[$revision->vid] = $revision; } @@ -2134,7 +2134,7 @@ function node_file_download_access($field, EntityInterface $entity, File $file) */ function node_language_delete($language) { // On nodes with this language, unset the language. - db_update('node') + db_update('node_revision') ->fields(array('langcode' => '')) ->condition('langcode', $language->id) ->execute(); diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc index a3ad643..df15382 100644 --- a/core/modules/node/node.views.inc +++ b/core/modules/node/node.views.inc @@ -198,25 +198,6 @@ function node_views_data() { ), ); - if (module_exists('language')) { - $data['node']['langcode'] = array( - 'title' => t('Language'), - 'help' => t('The language the content is in.'), - 'field' => array( - 'id' => 'node_language', - ), - 'filter' => array( - 'id' => 'language', - ), - 'argument' => array( - 'id' => 'language', - ), - 'sort' => array( - 'id' => 'standard', - ), - ); - } - if (\Drupal::moduleHandler()->moduleExists('content_translation')) { $data['node']['translation_link'] = array( 'title' => t('Translation link'), @@ -419,15 +400,14 @@ function node_views_data() { ), ); - $data['node_field_revision']['table']['entity type'] = 'node'; + $data['node_revision']['table']['entity type'] = 'node'; // Define the base group of this table. Fields that don't have a group defined // will go into this field by default. - $data['node_field_revision']['table']['group'] = t('Content revision'); - $data['node_field_revision']['table']['wizard_id'] = 'node_revision'; - + $data['node_revision']['table']['group'] = t('Content revision'); + $data['node_revision']['table']['wizard_id'] = 'node_revision'; // Advertise this table as a possible base table. - $data['node_field_revision']['table']['base'] = array( + $data['node_revision']['table']['base'] = array( 'field' => 'vid', 'title' => t('Content revision'), 'help' => t('Content revision is a history of changes to content.'), @@ -437,25 +417,14 @@ function node_views_data() { ); // For other base tables, explain how we join. - $data['node_field_revision']['table']['join'] = array( + $data['node_revision']['table']['join'] = array( 'node' => array( 'left_field' => 'vid', 'field' => 'vid', ), ); - $data['node_field_revision']['revision_uid'] = array( - 'title' => t('User'), - 'help' => t('Relate a content revision to the user who created the revision.'), - 'relationship' => array( - 'id' => 'standard', - 'base' => 'users', - 'base field' => 'uid', - 'label' => t('revision user'), - ), - ); - - $data['node_field_revision']['nid'] = array( + $data['node_revision']['nid'] = array( 'title' => t('Nid'), 'help' => t('The revision NID of the content revision.'), 'field' => array( @@ -480,7 +449,7 @@ function node_views_data() { ), ); - $data['node_field_revision']['vid'] = array( + $data['node_revision']['vid'] = array( 'title' => t('Vid'), 'help' => t('The revision ID of the content revision.'), 'field' => array( @@ -505,6 +474,61 @@ function node_views_data() { ), ); + if (Drupal::moduleHandler()->moduleExists('language')) { + $data['node_revision']['langcode'] = array( + 'title' => t('Language'), + 'help' => t('The language the content is in.'), + 'field' => array( + 'id' => 'node_language', + ), + 'filter' => array( + 'id' => 'language', + ), + 'argument' => array( + 'id' => 'language', + ), + 'sort' => array( + 'id' => 'standard', + ), + ); + } + + $data['node_revision']['log'] = array( + 'title' => t('Log message'), + 'help' => t('The log message entered when the revision was created.'), + 'field' => array( + 'id' => 'xss', + ), + 'filter' => array( + 'id' => 'string', + ), + ); + + $data['node_revision']['revision_uid'] = array( + 'title' => t('User'), + 'help' => t('Relate a content revision to the user who created the revision.'), + 'relationship' => array( + 'id' => 'standard', + 'base' => 'users', + 'base field' => 'uid', + 'label' => t('revision user'), + ), + ); + + $data['node_field_revision']['table']['entity type'] = 'node'; + // Define the base group of this table. Fields that don't have a group defined + // will go into this field by default. + $data['node_field_revision']['table']['group'] = t('Content revision'); + $data['node_field_revision']['table']['wizard_id'] = 'node_field_revision'; + + // For other base tables, explain how we join. + $data['node_field_revision']['table']['join'] = array( + 'node' => array( + 'left_field' => 'vid', + 'field' => 'vid', + ), + ); + $data['node_field_revision']['status'] = array( 'title' => t('Published'), 'help' => t('Whether or not the content is published.'), @@ -544,17 +568,6 @@ function node_views_data() { ), ); - $data['node_field_revision']['log'] = array( - 'title' => t('Log message'), - 'help' => t('The log message entered when the revision was created.'), - 'field' => array( - 'id' => 'xss', - ), - 'filter' => array( - 'id' => 'string', - ), - ); - $data['node_field_revision']['changed'] = array( 'title' => t('Updated date'), 'help' => t('The date the node was last updated.'), @@ -569,7 +582,7 @@ function node_views_data() { ), ); - $data['node_field_revision']['link_to_revision'] = array( + $data['node_revision']['link_to_revision'] = array( 'field' => array( 'title' => t('Link to revision'), 'help' => t('Provide a simple link to the revision.'), @@ -578,7 +591,7 @@ function node_views_data() { ), ); - $data['node_field_revision']['revert_revision'] = array( + $data['node_revision']['revert_revision'] = array( 'field' => array( 'title' => t('Link to revert revision'), 'help' => t('Provide a simple link to revert to the revision.'), @@ -587,7 +600,7 @@ function node_views_data() { ), ); - $data['node_field_revision']['delete_revision'] = array( + $data['node_revision']['delete_revision'] = array( 'field' => array( 'title' => t('Link to delete revision'), 'help' => t('Provide a simple link to delete the content revision.'), diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_nid.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_nid.yml index c4e06a3..24ca887 100644 --- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_nid.yml +++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_nid.yml @@ -1,5 +1,5 @@ id: test_node_revision_nid -base_table: node_field_revision +base_table: node_revision core: 8 display: default: @@ -7,7 +7,7 @@ display: relationships: nid: id: nid - table: node_field_revision + table: node_revision field: nid required: true plugin_id: standard @@ -15,13 +15,13 @@ display: fields: vid: id: vid - table: node_field_revision + table: node_revision field: vid plugin_id: standard provider: views nid_1: id: nid_1 - table: node_field_revision + table: node_revision field: nid plugin_id: standard provider: views @@ -35,7 +35,7 @@ display: arguments: nid: id: nid - table: node_field_revision + table: node_revision field: nid plugin_id: node_nid provider: node diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_vid.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_vid.yml index 38664e1..581aa2b 100644 --- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_vid.yml +++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_revision_vid.yml @@ -1,5 +1,5 @@ id: test_node_revision_vid -base_table: node_field_revision +base_table: node_revision core: 8 display: default: @@ -7,7 +7,7 @@ display: relationships: vid: id: vid - table: node_field_revision + table: node_revision field: vid required: true plugin_id: standard @@ -15,13 +15,13 @@ display: fields: vid: id: vid - table: node_field_revision + table: node_revision field: vid plugin_id: standard provider: views nid_1: id: nid_1 - table: node_field_revision + table: node_revision field: nid plugin_id: standard provider: views @@ -35,7 +35,7 @@ display: arguments: nid: id: nid - table: node_field_revision + table: node_revision field: nid plugin_id: node_nid provider: node diff --git a/core/modules/serialization/lib/Drupal/serialization/Tests/NormalizerTestBase.php b/core/modules/serialization/lib/Drupal/serialization/Tests/NormalizerTestBase.php index 977437b..45a4490 100644 --- a/core/modules/serialization/lib/Drupal/serialization/Tests/NormalizerTestBase.php +++ b/core/modules/serialization/lib/Drupal/serialization/Tests/NormalizerTestBase.php @@ -21,8 +21,8 @@ protected function setUp() { parent::setUp(); - $this->installSchema('entity_test', array('entity_test_mulrev', 'entity_test_mulrev_property_revision', 'entity_test_mulrev_property_data')); $this->installSchema('user', array('users', 'users_roles')); + $this->installSchema('entity_test', array('entity_test_mulrev', 'entity_test_mulrev_revision', 'entity_test_mulrev_property_revision', 'entity_test_mulrev_property_data')); $this->installSchema('system', array('url_alias')); $this->installConfig(array('field')); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php index 57f9355..b239199 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php @@ -31,6 +31,7 @@ public function setUp() { 'entity_test_rev', 'entity_test_rev_revision', 'entity_test_mulrev', + 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision' )); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php index 84231d3..dd24e18 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php @@ -44,7 +44,7 @@ public static function getInfo() { public function setUp() { parent::setUp(); $this->installSchema('user', array('users_data')); - $this->installSchema('node', array('node', 'node_field_data', 'node_field_revision', 'node_access')); + $this->installSchema('node', array('node', 'node_revision', 'node_field_data', 'node_field_revision', 'node_access')); $this->installSchema('comment', array('comment', 'node_comment_statistics')); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php index 9bf20e2..044f5bd 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php @@ -37,13 +37,14 @@ public static function getInfo() { public function setUp() { parent::setUp(); $this->installSchema('user', array('users_data')); - $this->installSchema('node', array('node', 'node_field_data', 'node_field_revision', 'node_access')); + $this->installSchema('node', array('node', 'node_revision', 'node_field_data', 'node_field_revision', 'node_access')); $this->installSchema('entity_test', array( 'entity_test_mul', 'entity_test_mul_property_data', 'entity_test_rev', 'entity_test_rev_revision', 'entity_test_mulrev', + 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision' )); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php index bdc3cc9..72950e1 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php @@ -57,7 +57,7 @@ public static function getInfo() { function setUp() { parent::setUp(); - $this->installSchema('entity_test', array('entity_test_mulrev', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision')); + $this->installSchema('entity_test', array('entity_test_mulrev', 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision')); $this->installSchema('system', array('variable')); $this->installConfig(array('language')); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php index d6fb956..e4b7175 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php @@ -37,6 +37,7 @@ function setUp() { 'entity_test_rev', 'entity_test_rev_revision', 'entity_test_mulrev', + 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision', )); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUUIDTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUUIDTest.php index 0168bb3..30e7c79 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUUIDTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUUIDTest.php @@ -31,6 +31,7 @@ public function setUp() { 'entity_test_rev', 'entity_test_rev_revision', 'entity_test_mulrev', + 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision', )); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php index b17a700..0301686 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php @@ -44,6 +44,7 @@ public function setUp() { 'entity_test_rev', 'entity_test_rev_revision', 'entity_test_mulrev', + 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision' )); diff --git a/core/modules/system/tests/modules/entity_test/entity_test.install b/core/modules/system/tests/modules/entity_test/entity_test.install index 346eccb..a03acf0 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.install +++ b/core/modules/system/tests/modules/entity_test/entity_test.install @@ -120,13 +120,6 @@ function entity_test_schema() { 'not null' => TRUE, 'default' => '', ), - 'langcode' => array( - 'description' => 'The {language}.langcode of the original variant of this test entity.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), 'name' => array( 'description' => 'The name of the test entity.', 'type' => 'varchar', @@ -134,6 +127,13 @@ function entity_test_schema() { 'not null' => TRUE, 'default' => '', ), + 'user_id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => NULL, + 'description' => 'The {users}.uid of the associated user.', + ), ), 'primary key' => array('id'), 'unique keys' => array( @@ -184,7 +184,7 @@ function entity_test_schema() { 'user_id' => array('users' => 'uid'), 'id' => array('entity_test_rev' => 'id'), ), - 'primary key' => array('revision_id', 'id', 'langcode'), + 'primary key' => array('revision_id'), ); // Schema for entity with data table. @@ -297,18 +297,39 @@ function entity_test_schema() { 'not null' => TRUE, 'default' => '', ), + ), + 'primary key' => array('id'), + 'unique keys' => array( + 'uuid' => array('uuid'), + ), + ); + $schema['entity_test_mulrev_revision'] = array( + 'description' => 'Stores entity_test_rev item property revisions.', + 'fields' => array( + 'id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The {entity_test_rev}.id of the test entity.', + ), + 'revision_id' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The primary identifier for this version.', + ), 'langcode' => array( - 'description' => 'The {language}.langcode of the original variant of this test entity.', + 'description' => 'The {language}.langcode of this variant of this test entity.', 'type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => '', ), ), - 'primary key' => array('id'), - 'unique keys' => array( - 'uuid' => array('uuid'), + 'foreign keys' => array( + 'id' => array('entity_test_rev' => 'id'), ), + 'primary key' => array('revision_id'), ); $schema['entity_test_mulrev_property_data'] = array( 'description' => 'Stores entity_test_mulrev item properties.', @@ -373,7 +394,7 @@ function entity_test_schema() { 'description' => 'The {entity_test_mulrev}.id of the test entity.', ), 'revision_id' => array( - 'type' => 'serial', + 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'description' => 'The primary identifier for this version.', @@ -413,7 +434,7 @@ function entity_test_schema() { 'user_id' => array('users' => 'uid'), 'id' => array('entity_test_mulrev' => 'id'), ), - 'primary key' => array('revision_id', 'id', 'langcode'), + 'primary key' => array('revision_id', 'langcode'), ); return $schema; diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMulRev.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMulRev.php index 4a578e2..5dc9dcc 100644 --- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMulRev.php +++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMulRev.php @@ -28,7 +28,8 @@ * }, * base_table = "entity_test_mulrev", * data_table = "entity_test_mulrev_property_data", - * revision_table = "entity_test_mulrev_property_revision", + * revision_table = "entity_test_mulrev_revision", + * revision_data_table = "entity_test_mulrev_property_revision", * fieldable = TRUE, * translatable = TRUE, * entity_keys = { diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module index bd1bf31..ece0801 100644 --- a/core/modules/translation/translation.module +++ b/core/modules/translation/translation.module @@ -499,7 +499,7 @@ function translation_node_get_translations($tnid) { if (!isset($translations[$tnid])) { $translations[$tnid] = array(); $query = db_select('node_field_data', 'n'); - $query->innerJoin('node', 'nb', 'nb.nid = n.nid AND nb.langcode = n.langcode'); + $query->innerJoin('node', 'nb', 'nb.nid = n.nid'); $query->fields('n', array('nid', 'uid', 'status', 'title', 'langcode')) ->fields('nb', array('type')) ->condition('nb.tnid', $tnid) diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php b/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php index 4fc1fc8..c3348dc 100644 --- a/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php @@ -295,7 +295,7 @@ public function testFetchBaseTables() { // Test the number of tables returned and their order. $this->assertEqual(count($base_tables), 3, 'The correct amount of base tables were returned.'); - $this->assertIdentical(array_keys($base_tables), array('node', 'node_field_revision', 'views_test_data'), 'The tables are sorted as expected.'); + $this->assertIdentical(array_keys($base_tables), array('node', 'node_revision', 'views_test_data'), 'The tables are sorted as expected.'); // Test the values returned for each base table. $defaults = array(