/** * {@inheritdoc} */ protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { $entity_type_id = $entity->getEntityTypeId(); if ($entity instanceof ContentEntityInterface && $entity->isDefaultRevision() || !$entity->getEntityType()->isRevisionable()) { $build['#contextual_links'][$entity_type_id] = ['route_parameters' => [$entity_type_id => $entity->id()]]; } else { $build['#contextual_links'][$entity_type_id . '_revision'] = ['route_parameters' => [$entity_type_id => $entity->id(), $entity_type_id . '_revision' => $entity->getRevisionId()]]; } }
/** * Saves values of configurable fields for an entity. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity. * @param bool $update * TRUE if the entity is being updated, FALSE if it is being inserted. */ protected function saveFieldItems(EntityInterface $entity, $update = TRUE) { $vid = $entity->getRevisionId(); $id = $entity->id(); $bundle = $entity->bundle(); $entity_type = $entity->getEntityTypeId(); $default_langcode = $entity->getUntranslated()->language()->id; $translation_langcodes = array_keys($entity->getTranslationLanguages()); if (!isset($vid)) { $vid = $id; } foreach ($this->entityManager->getFieldDefinitions($entity_type, $bundle) as $field_name => $field_definition) { $storage_definition = $field_definition->getFieldStorageDefinition(); if (!$this->usesDedicatedTable($storage_definition)) { continue; } $table_name = static::_fieldTableName($storage_definition); $revision_name = static::_fieldRevisionTableName($storage_definition); // Delete and insert, rather than update, in case a value was added. if ($update) { // Only overwrite the field's base table if saving the default revision // of an entity. if ($entity->isDefaultRevision()) { $this->database->delete($table_name)->condition('entity_id', $id)->execute(); } $this->database->delete($revision_name)->condition('entity_id', $id)->condition('revision_id', $vid)->execute(); } // Prepare the multi-insert query. $do_insert = FALSE; $columns = array('entity_id', 'revision_id', 'bundle', 'delta', 'langcode'); foreach ($storage_definition->getColumns() as $column => $attributes) { $columns[] = static::_fieldColumnName($storage_definition, $column); } $query = $this->database->insert($table_name)->fields($columns); $revision_query = $this->database->insert($revision_name)->fields($columns); $langcodes = $field_definition->isTranslatable() ? $translation_langcodes : array($default_langcode); foreach ($langcodes as $langcode) { $delta_count = 0; $items = $entity->getTranslation($langcode)->get($field_name); $items->filterEmptyItems(); foreach ($items as $delta => $item) { // We now know we have someting to insert. $do_insert = TRUE; $record = array('entity_id' => $id, 'revision_id' => $vid, 'bundle' => $bundle, 'delta' => $delta, 'langcode' => $langcode); foreach ($storage_definition->getColumns() as $column => $attributes) { $column_name = static::_fieldColumnName($storage_definition, $column); // Serialize the value if specified in the column schema. $record[$column_name] = !empty($attributes['serialize']) ? serialize($item->{$column}) : $item->{$column}; } $query->values($record); $revision_query->values($record); if ($storage_definition->getCardinality() != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && ++$delta_count == $storage_definition->getCardinality()) { break; } } } // Execute the query if we have values to insert. if ($do_insert) { // Only overwrite the field's base table if saving the default revision // of an entity. if ($entity->isDefaultRevision()) { $query->execute(); } $revision_query->execute(); } } }
/** * {@inheritdoc} */ protected function doSave($id, EntityInterface $entity) { /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ if ($entity->isNew()) { // Ensure the entity is still seen as new after assigning it an id, while // storing its data. $entity->enforceIsNew(); if ($this->entityType->isRevisionable()) { $entity->setNewRevision(); } $return = SAVED_NEW; } else { // @todo Consider returning a different value when saving a non-default // entity revision. See https://www.drupal.org/node/2509360. $return = $entity->isDefaultRevision() ? SAVED_UPDATED : FALSE; } $this->populateAffectedRevisionTranslations($entity); $this->doSaveFieldItems($entity); return $return; }
/** * {@inheritdoc} * * @todo Revisit this logic with forward revisions in mind. */ protected function doSave($id, EntityInterface $entity) { if ($entity->_rev->is_stub) { $entity->isDefaultRevision(TRUE); } else { // Enforce new revision if any module messed with it in a hook. $entity->setNewRevision(); // Decide whether or not this is the default revision. if (!$entity->isNew()) { $default_rev = \Drupal::service('entity.index.rev.tree')->getDefaultRevision($entity->uuid()); if ($entity->_rev->value == $default_rev) { $entity->isDefaultRevision(TRUE); } else { $entity->isDefaultRevision(FALSE); } } } return parent::doSave($id, $entity); }