diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index ce12db5202dcc97c4af6837e31d09e37459a2706..38e963ed94a9cd5bbba1795840daedbe060bce22 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -203,6 +203,13 @@ drupal.dropbutton:
- core/drupalSettings
- core/jquery.once
+drupal.entity-form:
+ version: VERSION
+ js:
+ misc/entity-form.js: {}
+ dependencies:
+ - core/drupal.form
+
drupal.form:
version: VERSION
js:
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityForm.php b/core/lib/Drupal/Core/Entity/ContentEntityForm.php
index 29b0a9b7bf7cb95bd50ddff1cb0503e33246914b..e131e9be4eae0fa131a5257180d3636eed1e901e 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityForm.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityForm.php
@@ -2,6 +2,7 @@
namespace Drupal\Core\Entity;
+use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Form\FormStateInterface;
@@ -21,14 +22,42 @@ class ContentEntityForm extends EntityForm implements ContentEntityFormInterface
*/
protected $entityManager;
+ /**
+ * The entity being used by this form.
+ *
+ * @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\Core\Entity\RevisionLogInterface
+ */
+ protected $entity;
+
+ /**
+ * The entity type bundle info service.
+ *
+ * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+ */
+ protected $entityTypeBundleInfo;
+
+ /**
+ * The time service.
+ *
+ * @var \Drupal\Component\Datetime\TimeInterface
+ */
+ protected $time;
+
/**
* Constructs a ContentEntityForm object.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
+ * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
+ * The entity type bundle service.
+ * @param \Drupal\Component\Datetime\TimeInterface $time
+ * The time service.
*/
- public function __construct(EntityManagerInterface $entity_manager) {
+ public function __construct(EntityManagerInterface $entity_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL) {
$this->entityManager = $entity_manager;
+
+ $this->entityTypeBundleInfo = $entity_type_bundle_info ?: \Drupal::service('entity_type.bundle.info');
+ $this->time = $time ?: \Drupal::service('datetime.time');
}
/**
@@ -36,15 +65,54 @@ public function __construct(EntityManagerInterface $entity_manager) {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('entity.manager')
+ $container->get('entity.manager'),
+ $container->get('entity_type.bundle.info'),
+ $container->get('datetime.time')
);
}
+ /**
+ * {@inheritdoc}
+ */
+ protected function prepareEntity() {
+ parent::prepareEntity();
+
+ // Hide the current revision log message in UI.
+ if ($this->showRevisionUi() && !$this->entity->isNew()) {
+ $this->entity->setRevisionLogMessage(NULL);
+ }
+ }
+
+ /**
+ * Returns the bundle entity of the entity, or NULL if there is none.
+ *
+ * @return \Drupal\Core\Entity\EntityInterface|null
+ * The bundle entity.
+ */
+ protected function getBundleEntity() {
+ if ($bundle_entity_type = $this->entity->getEntityType()->getBundleEntityType()) {
+ return $this->entityTypeManager->getStorage($bundle_entity_type)->load($this->entity->bundle());
+ }
+ return NULL;
+ }
+
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
+
+ if ($this->showRevisionUi()) {
+ // Advanced tab must be the first, because other fields rely on that.
+ if (!isset($form['advanced'])) {
+ $form['advanced'] = [
+ '#type' => 'vertical_tabs',
+ '#weight' => 99,
+ ];
+ }
+ }
+
$form = parent::form($form, $form_state);
+
// Content entity forms do not use the parent's #after_build callback
// because they only need to rebuild the entity in the validation and the
// submit handler because Field API uses its own #after_build callback for
@@ -54,6 +122,11 @@ public function form(array $form, FormStateInterface $form_state) {
$this->getFormDisplay($form_state)->buildForm($this->entity, $form, $form_state);
// Allow modules to act before and after form language is updated.
$form['#entity_builders']['update_form_langcode'] = '::updateFormLangcode';
+
+ if ($this->showRevisionUi()) {
+ $this->addRevisionableFormFields($form);
+ }
+
return $form;
}
@@ -76,6 +149,17 @@ public function buildEntity(array $form, FormStateInterface $form_state) {
// Mark the entity as requiring validation.
$entity->setValidationRequired(!$form_state->getTemporaryValue('entity_validated'));
+ // Save as a new revision if requested to do so.
+ if ($this->showRevisionUi() && !$form_state->isValueEmpty('revision')) {
+ $entity->setNewRevision();
+ if ($entity instanceof RevisionLogInterface) {
+ // If a new revision is created, save the current user as
+ // revision author.
+ $entity->setRevisionUserId($this->currentUser()->id());
+ $entity->setRevisionCreationTime($this->time->getRequestTime());
+ }
+ }
+
return $entity;
}
@@ -283,8 +367,84 @@ public function updateFormLangcode($entity_type_id, EntityInterface $entity, arr
*/
public function updateChangedTime(EntityInterface $entity) {
if ($entity->getEntityType()->isSubclassOf(EntityChangedInterface::class)) {
- $entity->setChangedTime(REQUEST_TIME);
+ $entity->setChangedTime($this->time->getRequestTime());
}
}
+ /**
+ * Add revision form fields if the entity enabled the UI.
+ *
+ * @param array $form
+ * An associative array containing the structure of the form.
+ */
+ protected function addRevisionableFormFields(array &$form) {
+ $entity_type = $this->entity->getEntityType();
+
+ $new_revision_default = $this->getNewRevisionDefault();
+
+ // Add a log field if the "Create new revision" option is checked, or if the
+ // current user has the ability to check that option.
+ $form['revision_information'] = [
+ '#type' => 'details',
+ '#title' => $this->t('Revision information'),
+ // Open by default when "Create new revision" is checked.
+ '#open' => $new_revision_default,
+ '#group' => 'advanced',
+ '#weight' => 20,
+ '#access' => $new_revision_default || $this->entity->get($entity_type->getKey('revision'))->access('update'),
+ '#optional' => TRUE,
+ '#attributes' => [
+ 'class' => ['entity-content-form-revision-information'],
+ ],
+ '#attached' => [
+ 'library' => ['core/drupal.entity-form'],
+ ],
+ ];
+
+ $form['revision'] = [
+ '#type' => 'checkbox',
+ '#title' => $this->t('Create new revision'),
+ '#default_value' => $new_revision_default,
+ '#access' => !$this->entity->isNew() && $this->entity->get($entity_type->getKey('revision'))->access('update'),
+ '#group' => 'revision_information',
+ ];
+
+ if (isset($form['revision_log'])) {
+ $form['revision_log'] += [
+ '#group' => 'revision_information',
+ '#states' => [
+ 'visible' => [
+ ':input[name="revision"]' => ['checked' => TRUE],
+ ],
+ ],
+ ];
+ }
+ }
+
+ /**
+ * Should new revisions created on default.
+ *
+ * @return bool
+ * New revision on default.
+ */
+ protected function getNewRevisionDefault() {
+ $new_revision_default = FALSE;
+ $bundle_entity = $this->getBundleEntity();
+ if ($bundle_entity instanceof RevisionableEntityBundleInterface) {
+ // Always use the default revision setting.
+ $new_revision_default = $bundle_entity->shouldCreateNewRevision();
+ }
+ return $new_revision_default;
+ }
+
+ /**
+ * Checks whether the revision form fields should be added to the form.
+ *
+ * @return bool
+ * TRUE if the form field should be added, FALSE otherwise.
+ */
+ protected function showRevisionUi() {
+ return $this->entity->getEntityType()->showRevisionUi();
+ }
+
}
diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php
index 89b83cf098ae5baf091c552f08f179912b399012..78fb2ffbc2bd15d7624391350c10aca42c448485 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -174,6 +174,13 @@ class EntityType implements EntityTypeInterface {
*/
protected $translatable = FALSE;
+ /**
+ * Indicates whether the revision form fields should be added to the form.
+ *
+ * @var bool
+ */
+ protected $show_revision_ui = FALSE;
+
/**
* The human-readable name of the type.
*
@@ -689,6 +696,13 @@ public function getBaseTable() {
return $this->base_table;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function showRevisionUi() {
+ return $this->isRevisionable() && $this->show_revision_ui;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index c6336c950c58df395fb330798f64f44f14f9fd6c..60d60b563326fe71f838fa772944c38097b5f1b6 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -573,6 +573,14 @@ public function getBaseTable();
*/
public function isTranslatable();
+ /**
+ * Indicates whether the revision form fields should be added to the form.
+ *
+ * @return bool
+ * TRUE if the form field should be added, FALSE otherwise.
+ */
+ public function showRevisionUi();
+
/**
* Indicates whether entities of this type have revision support.
*
diff --git a/core/lib/Drupal/Core/Entity/RevisionableEntityBundleInterface.php b/core/lib/Drupal/Core/Entity/RevisionableEntityBundleInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..caf44f20a3f4858b8fecb27dc24979e4236cc1b5
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/RevisionableEntityBundleInterface.php
@@ -0,0 +1,20 @@
+blockContentStorage = $block_content_storage;
- $this->blockContentTypeStorage = $block_content_type_storage;
- $this->languageManager = $language_manager;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container) {
- $entity_manager = $container->get('entity.manager');
- return new static(
- $entity_manager,
- $entity_manager->getStorage('block_content'),
- $entity_manager->getStorage('block_content_type'),
- $container->get('language_manager')
- );
- }
-
- /**
- * Overrides \Drupal\Core\Entity\EntityForm::prepareEntity().
- *
- * Prepares the custom block object.
- *
- * Fills in a few default values, and then invokes
- * hook_block_content_prepare() on all modules.
- */
- protected function prepareEntity() {
- $block = $this->entity;
- // Set up default values, if required.
- $block_type = $this->blockContentTypeStorage->load($block->bundle());
- if (!$block->isNew()) {
- $block->setRevisionLogMessage(NULL);
- }
- // Always use the default revision setting.
- $block->setNewRevision($block_type->shouldCreateNewRevision());
- }
-
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
$block = $this->entity;
- $account = $this->currentUser();
+
+ $form = parent::form($form, $form_state);
if ($this->operation == 'edit') {
$form['#title'] = $this->t('Edit custom block %label', array('%label' => $block->label()));
@@ -109,56 +34,7 @@ public function form(array $form, FormStateInterface $form_state) {
// names.
$form['#attributes']['class'][0] = 'block-' . Html::getClass($block->bundle()) . '-form';
- $form['advanced'] = array(
- '#type' => 'vertical_tabs',
- '#weight' => 99,
- );
-
- // Add a log field if the "Create new revision" option is checked, or if the
- // current user has the ability to check that option.
- $form['revision_information'] = array(
- '#type' => 'details',
- '#title' => $this->t('Revision information'),
- // Open by default when "Create new revision" is checked.
- '#open' => $block->isNewRevision(),
- '#group' => 'advanced',
- '#attributes' => array(
- 'class' => array('block-content-form-revision-information'),
- ),
- '#attached' => array(
- 'library' => array('block_content/drupal.block_content'),
- ),
- '#weight' => 20,
- '#access' => $block->isNewRevision() || $account->hasPermission('administer blocks'),
- );
-
- $form['revision_information']['revision'] = array(
- '#type' => 'checkbox',
- '#title' => $this->t('Create new revision'),
- '#default_value' => $block->isNewRevision(),
- '#access' => $account->hasPermission('administer blocks'),
- );
-
- // Check the revision log checkbox when the log textarea is filled in.
- // This must not happen if "Create new revision" is enabled by default,
- // since the state would auto-disable the checkbox otherwise.
- if (!$block->isNewRevision()) {
- $form['revision_information']['revision']['#states'] = array(
- 'checked' => array(
- 'textarea[name="revision_log"]' => array('empty' => FALSE),
- ),
- );
- }
-
- $form['revision_information']['revision_log'] = array(
- '#type' => 'textarea',
- '#title' => $this->t('Revision log message'),
- '#rows' => 4,
- '#default_value' => $block->getRevisionLog(),
- '#description' => $this->t('Briefly describe the changes you have made.'),
- );
-
- return parent::form($form, $form_state, $block);
+ return $form;
}
/**
@@ -167,19 +43,11 @@ public function form(array $form, FormStateInterface $form_state) {
public function save(array $form, FormStateInterface $form_state) {
$block = $this->entity;
- // Save as a new revision if requested to do so.
- if (!$form_state->isValueEmpty('revision')) {
- $block->setNewRevision();
- // If a new revision is created, save the current user as revision author.
- $block->setRevisionCreationTime(REQUEST_TIME);
- $block->setRevisionUserId(\Drupal::currentUser()->id());
- }
-
$insert = $block->isNew();
$block->save();
$context = array('@type' => $block->bundle(), '%info' => $block->label());
$logger = $this->logger('block_content');
- $block_type = $this->blockContentTypeStorage->load($block->bundle());
+ $block_type = $this->getBundleEntity();
$t_args = array('@type' => $block_type->label(), '%info' => $block->label());
if ($insert) {
diff --git a/core/modules/block_content/src/BlockContentTranslationHandler.php b/core/modules/block_content/src/BlockContentTranslationHandler.php
index 781ba1b6dc39469b33454752e071d40d69b1d280..b446cde8c5193c00236db8997cc5e76a57c4d3ff 100644
--- a/core/modules/block_content/src/BlockContentTranslationHandler.php
+++ b/core/modules/block_content/src/BlockContentTranslationHandler.php
@@ -5,30 +5,12 @@
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Core\Entity\EntityInterface;
use Drupal\content_translation\ContentTranslationHandler;
-use Drupal\Core\Form\FormStateInterface;
/**
* Defines the translation handler for custom blocks.
*/
class BlockContentTranslationHandler extends ContentTranslationHandler {
- /**
- * {@inheritdoc}
- */
- public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) {
- parent::entityFormAlter($form, $form_state, $entity);
- // Move the translation fieldset to a vertical tab.
- if (isset($form['translation'])) {
- $form['translation'] += array(
- '#group' => 'additional_settings',
- '#weight' => 100,
- '#attributes' => array(
- 'class' => array('block-content-translation-options'),
- ),
- );
- }
- }
-
/**
* {@inheritdoc}
*/
diff --git a/core/modules/block_content/src/BlockContentTypeInterface.php b/core/modules/block_content/src/BlockContentTypeInterface.php
index 9229dab8a81c358fd6920b5634a15534d656055c..da3864e1a080fe62683b306841b034d38f7b49f2 100644
--- a/core/modules/block_content/src/BlockContentTypeInterface.php
+++ b/core/modules/block_content/src/BlockContentTypeInterface.php
@@ -3,11 +3,12 @@
namespace Drupal\block_content;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Entity\RevisionableEntityBundleInterface;
/**
* Provides an interface defining a custom block type entity.
*/
-interface BlockContentTypeInterface extends ConfigEntityInterface {
+interface BlockContentTypeInterface extends ConfigEntityInterface, RevisionableEntityBundleInterface {
/**
* Returns the description of the block type.
@@ -17,12 +18,4 @@ interface BlockContentTypeInterface extends ConfigEntityInterface {
*/
public function getDescription();
- /**
- * Returns whether a new revision should be created by default.
- *
- * @return bool
- * TRUE if a new revision should be created by default.
- */
- public function shouldCreateNewRevision();
-
}
diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php
index 13af342934b4c022f4c5ead5c36cd8424bfe5aa4..51ae6f679c4a835e0237804fbd6072c0059f6bdf 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -35,6 +35,7 @@
* base_table = "block_content",
* revision_table = "block_content_revision",
* data_table = "block_content_field_data",
+ * show_revision_ui = TRUE,
* links = {
* "canonical" = "/block/{block_content}",
* "delete-form" = "/block/{block_content}/delete",
@@ -182,7 +183,14 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields['revision_log'] = BaseFieldDefinition::create('string_long')
->setLabel(t('Revision log message'))
->setDescription(t('The log entry explaining the changes in this revision.'))
- ->setRevisionable(TRUE);
+ ->setRevisionable(TRUE)
+ ->setDisplayOptions('form', array(
+ 'type' => 'string_textarea',
+ 'weight' => 25,
+ 'settings' => array(
+ 'rows' => 4,
+ ),
+ ));
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php
index 6fd225481570220ab8dbb3b681ce5e1f8c743747..7995125213422fc324e243fb0101815ecc0f3e91 100644
--- a/core/modules/content_translation/src/ContentTranslationHandler.php
+++ b/core/modules/content_translation/src/ContentTranslationHandler.php
@@ -384,6 +384,16 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En
'#multilingual' => TRUE,
);
+ if (isset($form['advanced'])) {
+ $form['content_translation'] += array(
+ '#group' => 'advanced',
+ '#weight' => 100,
+ '#attributes' => array(
+ 'class' => array('entity-translation-options'),
+ ),
+ );
+ }
+
// A new translation is enabled by default.
$metadata = $this->manager->getTranslationMetadata($entity);
$status = $new_translation || $metadata->isPublished();
diff --git a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
index ed372a926b6c329277b541435466417ec0076f4e..029ca49bcf1a633b91de20f91bdb336655fc9c69 100644
--- a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
+++ b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
@@ -49,7 +49,7 @@ class MenuLinkContentForm extends ContentEntityForm {
* The path validator.
*/
public function __construct(EntityManagerInterface $entity_manager, MenuParentFormSelectorInterface $menu_parent_selector, LanguageManagerInterface $language_manager, PathValidatorInterface $path_validator) {
- parent::__construct($entity_manager, $language_manager);
+ parent::__construct($entity_manager);
$this->menuParentSelector = $menu_parent_selector;
$this->pathValidator = $path_validator;
}
diff --git a/core/modules/node/node.js b/core/modules/node/node.js
index 98af6fdc16bba62606e9943167c54aef5285d5c5..086263d2a8e476edb6c1fa89f88f0b3d87f87b8d 100644
--- a/core/modules/node/node.js
+++ b/core/modules/node/node.js
@@ -18,21 +18,6 @@
Drupal.behaviors.nodeDetailsSummaries = {
attach: function (context) {
var $context = $(context);
- $context.find('.node-form-revision-information').drupalSetSummary(function (context) {
- var $revisionContext = $(context);
- var revisionCheckbox = $revisionContext.find('.js-form-item-revision input');
-
- // Return 'New revision' if the 'Create new revision' checkbox is
- // checked, or if the checkbox doesn't exist, but the revision log does.
- // For users without the "Administer content" permission the checkbox
- // won't appear, but the revision log will if the content type is set to
- // auto-revision.
- if (revisionCheckbox.is(':checked') || (!revisionCheckbox.length && $revisionContext.find('.js-form-item-revision-log textarea').length)) {
- return Drupal.t('New revision');
- }
-
- return Drupal.t('No revision');
- });
$context.find('.node-form-author').drupalSetSummary(function (context) {
var $authorContext = $(context);
@@ -64,22 +49,6 @@
return Drupal.t('Not promoted');
}
});
-
- $context.find('fieldset.node-translation-options').drupalSetSummary(function (context) {
- var $translationContext = $(context);
- var translate;
- var $checkbox = $translationContext.find('.js-form-item-translation-translate input');
-
- if ($checkbox.size()) {
- translate = $checkbox.is(':checked') ? Drupal.t('Needs to be updated') : Drupal.t('Does not need to be updated');
- }
- else {
- $checkbox = $translationContext.find('.js-form-item-translation-retranslate input');
- translate = $checkbox.is(':checked') ? Drupal.t('Flag other translations as outdated') : Drupal.t('Do not flag other translations as outdated');
- }
-
- return translate;
- });
}
};
diff --git a/core/modules/node/node.libraries.yml b/core/modules/node/node.libraries.yml
index 22c93ac7f35d969f320d3abebf2869c723f79369..59947a237de646024ff6622dce89f232b393541c 100644
--- a/core/modules/node/node.libraries.yml
+++ b/core/modules/node/node.libraries.yml
@@ -6,10 +6,8 @@ drupal.node:
js:
node.js: {}
dependencies:
- - core/jquery
- - core/drupal
+ - core/drupal.entity-form
- core/drupalSettings
- - core/drupal.form
drupal.node.preview:
version: VERSION
diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index f034957988eeda47418e231ded355d7d38fcdfef..68afc8360bcdf30f466de8657b712481e779397e 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -46,6 +46,7 @@
* data_table = "node_field_data",
* revision_table = "node_revision",
* revision_data_table = "node_field_revision",
+ * show_revision_ui = TRUE,
* translatable = TRUE,
* list_cache_contexts = { "user.node_grants:view" },
* entity_keys = {
diff --git a/core/modules/node/src/Entity/NodeType.php b/core/modules/node/src/Entity/NodeType.php
index 91d8a90959999c4bba07d311319f55e7754d791f..23f24a468bb54358403ca818baeb67955917ef8f 100644
--- a/core/modules/node/src/Entity/NodeType.php
+++ b/core/modules/node/src/Entity/NodeType.php
@@ -205,4 +205,11 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti
$storage->resetCache(array_keys($entities));
}
+ /**
+ * {@inheritdoc}
+ */
+ public function shouldCreateNewRevision() {
+ return $this->isNewRevision();
+ }
+
}
diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/NodeForm.php
index 282803009509541b738d85464623ac88a6bb9d86..41939234bc7e7eb7d87b26e879fc01308eb81a04 100644
--- a/core/modules/node/src/NodeForm.php
+++ b/core/modules/node/src/NodeForm.php
@@ -26,7 +26,7 @@ class NodeForm extends ContentEntityForm {
protected $hasBeenPreviewed = FALSE;
/**
- * Constructs a ContentEntityForm object.
+ * Constructs a NodeForm object.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
@@ -48,19 +48,6 @@ public static function create(ContainerInterface $container) {
);
}
- /**
- * {@inheritdoc}
- */
- protected function prepareEntity() {
- /** @var \Drupal\node\NodeInterface $node */
- $node = $this->entity;
-
- if (!$node->isNew()) {
- // Remove the revision log message from the original node entity.
- $node->revision_log = NULL;
- }
- }
-
/**
* {@inheritdoc}
*/
@@ -102,55 +89,15 @@ public function form(array $form, FormStateInterface $form_state) {
$form['#title'] = $this->t('Edit @type @title', array('@type' => node_get_type_label($node), '@title' => $node->label()));
}
- $current_user = $this->currentUser();
-
// Changed must be sent to the client, for later overwrite error checking.
$form['changed'] = array(
'#type' => 'hidden',
'#default_value' => $node->getChangedTime(),
);
- $form['advanced'] = array(
- '#type' => 'vertical_tabs',
- '#attributes' => array('class' => array('entity-meta')),
- '#weight' => 99,
- );
$form = parent::form($form, $form_state);
- // Add a revision_log field if the "Create new revision" option is checked,
- // or if the current user has the ability to check that option.
- $form['revision_information'] = array(
- '#type' => 'details',
- '#group' => 'advanced',
- '#title' => t('Revision information'),
- // Open by default when "Create new revision" is checked.
- '#open' => $node->isNewRevision(),
- '#attributes' => array(
- 'class' => array('node-form-revision-information'),
- ),
- '#attached' => array(
- 'library' => array('node/drupal.node'),
- ),
- '#weight' => 20,
- '#optional' => TRUE,
- );
-
- $form['revision'] = array(
- '#type' => 'checkbox',
- '#title' => t('Create new revision'),
- '#default_value' => $node->type->entity->isNewRevision(),
- '#access' => $current_user->hasPermission('administer nodes') && !$node->isNew(),
- '#group' => 'revision_information',
- );
-
- $form['revision_log'] += array(
- '#states' => array(
- 'visible' => array(
- ':input[name="revision"]' => array('checked' => TRUE),
- ),
- ),
- '#group' => 'revision_information',
- );
+ $form['advanced']['#attributes']['class'][] = 'entity-meta';
// Node author information for administrators.
$form['author'] = array(
@@ -303,32 +250,6 @@ protected function actions(array $form, FormStateInterface $form_state) {
return $element;
}
- /**
- * {@inheritdoc}
- *
- * Updates the node object by processing the submitted values.
- *
- * This function can be called by a "Next" button of a wizard to update the
- * form state's entity with the current step's values before proceeding to the
- * next step.
- */
- public function submitForm(array &$form, FormStateInterface $form_state) {
- // Build the node object from the submitted values.
- parent::submitForm($form, $form_state);
- $node = $this->entity;
-
- // Save as a new revision if requested to do so.
- if (!$form_state->isValueEmpty('revision') && $form_state->getValue('revision') != FALSE) {
- $node->setNewRevision();
- // If a new revision is created, save the current user as revision author.
- $node->setRevisionCreationTime(REQUEST_TIME);
- $node->setRevisionUserId(\Drupal::currentUser()->id());
- }
- else {
- $node->setNewRevision(FALSE);
- }
- }
-
/**
* Form submission handler for the 'preview' action.
*
diff --git a/core/modules/node/src/NodeTranslationHandler.php b/core/modules/node/src/NodeTranslationHandler.php
index 9c9741e1c3ed4750bc3452a5ba322d93a19dd0f1..2f6d2abfd938e4901c80f243c46f6c17c3088787 100644
--- a/core/modules/node/src/NodeTranslationHandler.php
+++ b/core/modules/node/src/NodeTranslationHandler.php
@@ -17,17 +17,7 @@ class NodeTranslationHandler extends ContentTranslationHandler {
public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) {
parent::entityFormAlter($form, $form_state, $entity);
- // Move the translation fieldset to a vertical tab.
if (isset($form['content_translation'])) {
- $form['content_translation'] += array(
- '#group' => 'advanced',
- '#attributes' => array(
- 'class' => array('node-translation-options'),
- ),
- );
-
- $form['content_translation']['#weight'] = 100;
-
// We do not need to show these values on node forms: they inherit the
// basic node property values.
$form['content_translation']['status']['#access'] = FALSE;
diff --git a/core/modules/node/src/NodeTypeInterface.php b/core/modules/node/src/NodeTypeInterface.php
index c034ffbee04de1e51366d8a394c9591e7eca4b31..df4831e566328771fce323c462b69d074dfd8991 100644
--- a/core/modules/node/src/NodeTypeInterface.php
+++ b/core/modules/node/src/NodeTypeInterface.php
@@ -3,11 +3,12 @@
namespace Drupal\node;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Entity\RevisionableEntityBundleInterface;
/**
* Provides an interface defining a node type entity.
*/
-interface NodeTypeInterface extends ConfigEntityInterface {
+interface NodeTypeInterface extends ConfigEntityInterface, RevisionableEntityBundleInterface {
/**
* Determines whether the node type is locked.
@@ -22,13 +23,17 @@ public function isLocked();
*
* @return bool
* TRUE if a new revision should be created by default.
+ *
+ * @deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use
+ * Drupal\Core\Entity\RevisionableEntityBundleInterface::shouldCreateNewRevision()
+ * instead.
*/
public function isNewRevision();
/**
* Sets whether a new revision should be created by default.
*
- * @param bool $new_revision_
+ * @param bool $new_revision
* TRUE if a new revision should be created by default.
*/
public function setNewRevision($new_revision);
diff --git a/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php b/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php
index 0f84d3d79a217e7fb5ea1b756a02291e1eb2a874..2f5c20a1cd59a1ad5d7e0da32e29eea67cef4d7d 100644
--- a/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php
+++ b/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php
@@ -29,7 +29,7 @@ class EntitySerializationTest extends NormalizerTestBase {
/**
* The test entity.
*
- * @var \Drupal\Core\Entity\ContentEntityBase
+ * @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\Core\Entity\RevisionLogInterface
*/
protected $entity;
@@ -76,6 +76,10 @@ protected function setUp() {
'value' => $this->randomMachineName(),
'format' => 'full_html',
),
+ 'revision_log_message' => array(
+ 'value' => 'Serialization revision message',
+ ),
+ 'revision_user' => $this->user->id(),
);
$this->entity = EntityTestMulRev::create($this->values);
$this->entity->save();
@@ -123,6 +127,20 @@ public function testNormalize() {
array('value' => TRUE),
),
'non_rev_field' => array(),
+ 'revision_created' => array(
+ array('value' => $this->entity->getRevisionCreationTime()),
+ ),
+ 'revision_user' => array(
+ array(
+ 'target_id' => $this->user->id(),
+ 'target_type' => $this->user->getEntityTypeId(),
+ 'target_uuid' => $this->user->uuid(),
+ 'url' => $this->user->url(),
+ ),
+ ),
+ 'revision_log_message' => array(
+ array('value' => $this->values['revision_log_message']['value']),
+ ),
'field_test_text' => array(
array(
'value' => $this->values['field_test_text']['value'],
@@ -192,6 +210,9 @@ public function testSerialize() {
'revision_id' => '' . $this->entity->getRevisionId() . '',
'default_langcode' => '1',
'non_rev_field' => '',
+ 'revision_created' => '' . $this->entity->getRevisionCreationTime() . '',
+ 'revision_user' => '' . $this->user->id() . '' . $this->user->getEntityTypeId() . '' . $this->user->uuid() . '' . $this->user->url() . '',
+ 'revision_log_message' => '' . $this->values['revision_log_message']['value'] . '',
'field_test_text' => '' . $this->values['field_test_text']['value'] . '' . $this->values['field_test_text']['format'] . '',
);
// Sort it in the same order as normalised.
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php
index 0ee28bf032dc7bdc585b67b9e4faf7b622e45aa5..f01675f60256dcec5ba9ebbfc694b5511dc60e8b 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php
@@ -27,6 +27,7 @@
* revision_data_table = "entity_test_mulrev_property_revision",
* admin_permission = "administer entity_test content",
* translatable = TRUE,
+ * show_revision_ui = TRUE,
* entity_keys = {
* "id" = "id",
* "uuid" = "uuid",
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestRev.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestRev.php
index 47035ea84f76c0f187e84030419761a478226eb7..49c5aca2d5535b8e1ed71f19a86d96c81fb8e905 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestRev.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestRev.php
@@ -3,6 +3,8 @@
namespace Drupal\entity_test\Entity;
use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\RevisionLogEntityTrait;
+use Drupal\Core\Entity\RevisionLogInterface;
use Drupal\Core\Field\BaseFieldDefinition;
/**
@@ -28,6 +30,7 @@
* base_table = "entity_test_rev",
* revision_table = "entity_test_rev_revision",
* admin_permission = "administer entity_test content",
+ * show_revision_ui = TRUE,
* entity_keys = {
* "id" = "id",
* "uuid" = "uuid",
@@ -45,7 +48,9 @@
* }
* )
*/
-class EntityTestRev extends EntityTest {
+class EntityTestRev extends EntityTest implements RevisionLogInterface {
+
+ use RevisionLogEntityTrait;
/**
* {@inheritdoc}
@@ -53,13 +58,8 @@ class EntityTestRev extends EntityTest {
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);
- $fields['revision_id'] = BaseFieldDefinition::create('integer')
- ->setLabel(t('Revision ID'))
- ->setDescription(t('The version id of the test entity.'))
- ->setReadOnly(TRUE)
- ->setSetting('unsigned', TRUE);
+ $fields += static::revisionLogBaseFieldDefinitions($entity_type);
- $fields['langcode']->setRevisionable(TRUE);
$fields['name']->setRevisionable(TRUE);
$fields['user_id']->setRevisionable(TRUE);
diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
index 60ba8e577084471b94d72727d146f0dfad69a4ae..acb84e5f1ef27f51ec40a2b23822211e8d6a3dee 100644
--- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
+++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
@@ -89,6 +89,12 @@ protected function setUp() {
$typed_data_manager->expects($this->any())
->method('createDataDefinition')
->willReturn($this->getMock('Drupal\Core\TypedData\DataDefinitionInterface'));
+
+ $typed_data_manager->expects($this->any())
+ ->method('getDefinition')
+ ->with($this->equalTo('field_item:string_long'))
+ ->willReturn(array('class' => '\Drupal\Core\Field\Plugin\Field\FieldType\StringLongItem'));
+
$this->baseEntityType = new TestEntityType([
'base_table' => 'entity_test',
'id' => 'entity_test',
@@ -1107,3 +1113,12 @@ function t($string, array $args = []) {
return strtr($string, $args);
}
}
+
+
+namespace Drupal\Core\Entity;
+
+if (!function_exists('t')) {
+ function t($string, array $args = []) {
+ return strtr($string, $args);
+ }
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
index 23cf0340c541060ea9167692a2a26d152fc52be0..e49ee7ea92d69e5d06111ebfd30c3c92786acaef 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
@@ -102,6 +102,9 @@ public function testEntityTypeUpdateWithoutData() {
$expected = array(
'entity_test_update' => array(
t('The %entity_type entity type needs to be updated.', ['%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel()]),
+ // The revision key is now defined, so the revision field needs to be
+ // created.
+ t('The %field_name field needs to be installed.', ['%field_name' => 'Revision ID']),
),
);
$this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected); //, 'EntityDefinitionUpdateManager reports the expected change summary.');
@@ -797,7 +800,7 @@ public function testBaseFieldEntityKeyUpdateWithExistingData() {
/**
* Check that field schema is correctly handled with long-named fields.
*/
- function testLongNameFieldIndexes() {
+ public function testLongNameFieldIndexes() {
$this->addLongNameBaseField();
$entity_type_id = 'entity_test_update';
$entity_type = $this->entityManager->getDefinition($entity_type_id);
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
index 56af88810c9bc0de6676f67fc4f9b4846a0f3337..5dc1a948d35f61b745e09401390c3b49b30351de 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
@@ -3,6 +3,7 @@
namespace Drupal\KernelTests\Core\Entity;
use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\RevisionLogInterface;
use Drupal\Core\Entity\TypedData\EntityDataDefinition;
use Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface;
use Drupal\Core\Field\BaseFieldDefinition;
@@ -572,6 +573,12 @@ protected function doTestDataStructureInterfaces($entity_type) {
// Field format.
NULL,
);
+
+ if ($entity instanceof RevisionLogInterface) {
+ // Adding empty string for revision message.
+ $target_strings[] = '';
+ }
+
asort($strings);
asort($target_strings);
$this->assertEqual(array_values($strings), array_values($target_strings), format_string('%entity_type: All contained strings found.', array('%entity_type' => $entity_type)));