diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index ce12db5..c4ca44c 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -203,6 +203,15 @@ drupal.dropbutton:
- core/drupalSettings
- core/jquery.once
+drupal.entity-form:
+ version: VERSION
+ js:
+ misc/entity-form.js: {}
+ dependencies:
+ - core/jquery
+ - core/drupal
+ - core/drupal.form
+
drupal.form:
version: VERSION
js:
diff --git a/core/lib/Drupal/Core/Entity/Form/RevisionableContentEntityForm.php b/core/lib/Drupal/Core/Entity/Form/RevisionableContentEntityForm.php
new file mode 100644
index 0000000..063e90d
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Form/RevisionableContentEntityForm.php
@@ -0,0 +1,219 @@
+entityTypeBundleInfo = $entity_type_bundle_info;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ return new static(
+ $container->get('entity.manager'),
+ $container->get('entity_type.bundle.info')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function prepareEntity() {
+ parent::prepareEntity();
+
+ // Hide the current revision log message in UI.
+ if (!$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) {
+
+ // Advanced tab must be the first, because other fields rely on that.
+ $form['advanced'] = [
+ '#type' => 'vertical_tabs',
+ '#weight' => 99,
+ ];
+
+ $form = parent::form($form, $form_state);
+
+ $entity_type = $this->entity->getEntityType();
+
+ if ($this->operation == 'edit') {
+
+ $bundle_info = $this->entityTypeBundleInfo->getBundleInfo($entity_type->id());
+ if ($bundle_info[$this->entity->bundle()]) {
+ $form['#title'] = $this->t('Edit @bundle_label @label', [
+ '@bundle_label' => $bundle_info[$this->entity->bundle()]['label'],
+ '@label' => $this->entity->label(),
+ ]);
+ }
+ else {
+ $form['#title'] = $this->t('Edit @label', [
+ '@label' => $this->entity->label(),
+ ]);
+ }
+ }
+
+ $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();
+ }
+
+ // 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',
+ ];
+
+ // 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 (!$new_revision_default) {
+ $form['revision']['#states'] = [
+ 'checked' => [
+ 'textarea[name="revision_log[0][value]"]' => ['empty' => FALSE],
+ ],
+ ];
+ }
+
+ if (isset($form['revision_log'])) {
+ $form['revision_log']['#group'] = 'revision_information';
+ }
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * Updates the content 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 entity object from the submitted values.
+ parent::submitForm($form, $form_state);
+ $entity = $this->entity;
+
+ // Save as a new revision if requested to do so.
+ if (!$form_state->isValueEmpty('revision')) {
+ $entity->setNewRevision();
+ // If a new revision is created, save the current user as revision author.
+ $entity->setRevisionUserId(\Drupal::currentUser()->id());
+ $entity->setRevisionCreationTime(REQUEST_TIME);
+ }
+ else {
+ $entity->setNewRevision(FALSE);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(array $form, FormStateInterface $form_state) {
+
+ $insert = $this->entity->isNew();
+ $this->entity->save();
+
+ $context = ['@type' => $this->entity->bundle(), '%info' => $this->entity->label()];
+ $logger = $this->logger($this->entity->getEntityTypeId());
+ $bundle_entity = $this->getBundleEntity();
+ $t_args = ['@type' => $bundle_entity ? $bundle_entity->label() : $this->entity->getEntityType()->getLabel(), '%label' => $this->entity->label()];
+
+ if ($insert) {
+ $logger->notice('@type: added %info.', $context);
+ drupal_set_message($this->t('@type %label has been created.', $t_args));
+ }
+ else {
+ $logger->notice('@type: updated %info.', $context);
+ drupal_set_message($this->t('@type %label has been updated.', $t_args));
+ }
+
+ if ($this->entity->getEntityType()->hasLinkTemplate('collection')) {
+ $form_state->setRedirectUrl($this->entity->toUrl('collection'));
+ }
+ else {
+ $form_state->setRedirectUrl($this->entity->toUrl('canonical'));
+ }
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Entity/RevisionableEntityBundleInterface.php b/core/lib/Drupal/Core/Entity/RevisionableEntityBundleInterface.php
new file mode 100644
index 0000000..caf44f2
--- /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()));
+ $form['#title'] = $this->t('Edit custom block %label', ['%label' => $block->label()]);
}
// Override the default CSS class name, since the user-defined custom block
// type name in 'TYPE-block-form' potentially clashes with third-party class
// 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;
}
/**
@@ -166,55 +42,21 @@ 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());
- $t_args = array('@type' => $block_type->label(), '%info' => $block->label());
- if ($insert) {
- $logger->notice('@type: added %info.', $context);
- drupal_set_message($this->t('@type %info has been created.', $t_args));
- }
- else {
- $logger->notice('@type: updated %info.', $context);
- drupal_set_message($this->t('@type %info has been updated.', $t_args));
- }
+ parent::save($form, $form_state);
- if ($block->id()) {
- $form_state->setValue('id', $block->id());
- $form_state->set('id', $block->id());
- if ($insert) {
- if (!$theme = $block->getTheme()) {
- $theme = $this->config('system.theme')->get('default');
- }
- $form_state->setRedirect(
- 'block.admin_add',
- array(
- 'plugin_id' => 'block_content:' . $block->uuid(),
- 'theme' => $theme,
- )
- );
- }
- else {
- $form_state->setRedirectUrl($block->urlInfo('collection'));
+ if ($insert) {
+ if (!$theme = $block->getTheme()) {
+ $theme = $this->config('system.theme')->get('default');
}
- }
- else {
- // In the unlikely case something went wrong on save, the block will be
- // rebuilt and block form redisplayed.
- drupal_set_message($this->t('The block could not be saved.'), 'error');
- $form_state->setRebuild();
+ $form_state->setRedirect(
+ 'block.admin_add',
+ [
+ 'plugin_id' => 'block_content:' . $block->uuid(),
+ 'theme' => $theme,
+ ]
+ );
}
}
diff --git a/core/modules/block_content/src/BlockContentTranslationHandler.php b/core/modules/block_content/src/BlockContentTranslationHandler.php
index 781ba1b..9a7c46d 100644
--- a/core/modules/block_content/src/BlockContentTranslationHandler.php
+++ b/core/modules/block_content/src/BlockContentTranslationHandler.php
@@ -15,23 +15,6 @@ 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}
- */
protected function entityFormTitle(EntityInterface $entity) {
$block_type = BlockContentType::load($entity->bundle());
return t('Edit @type @title', array('@type' => $block_type->label(), '@title' => $entity->label()));
diff --git a/core/modules/block_content/src/BlockContentTypeInterface.php b/core/modules/block_content/src/BlockContentTypeInterface.php
index 9229dab..da3864e 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 @@
*/
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 13af342..0f50fbc 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -182,7 +182,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 6fd2254..7995125 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/field/src/Tests/FormTest.php b/core/modules/field/src/Tests/FormTest.php
index 16625a9..f16886e 100644
--- a/core/modules/field/src/Tests/FormTest.php
+++ b/core/modules/field/src/Tests/FormTest.php
@@ -609,11 +609,11 @@ function testHiddenField() {
$this->drupalPostForm(NULL, array(), t('Save'));
preg_match('|' . $entity_type . '/manage/(\d+)|', $this->url, $match);
$id = $match[1];
- $this->assertText(t('entity_test_rev @id has been created.', array('@id' => $id)), 'Entity was created');
$storage = $this->container->get('entity_type.manager')
->getStorage($entity_type);
$entity = $storage->load($id);
+ $this->assertRaw(t('@type %label has been created.', ['@type' => 'Test entity - revisions', '%label' => $entity->label()]));
$this->assertEqual($entity->{$field_name}->value, 99, 'Default value was saved');
// Update the field to remove the default value, and switch to the default
@@ -634,7 +634,7 @@ function testHiddenField() {
$value = mt_rand(1, 127);
$edit = array("{$field_name}[0][value]" => $value);
$this->drupalPostForm(NULL, $edit, t('Save'));
- $this->assertText(t('entity_test_rev @id has been updated.', array('@id' => $id)), 'Entity was updated');
+ $this->assertRaw(t('@type %label has been updated.', ['@type' => 'Test entity - revisions', '%label' => $entity->label()]));
$storage->resetCache([$id]);
$entity = $storage->load($id);
$this->assertEqual($entity->{$field_name}->value, $value, 'Field value was updated');
diff --git a/core/modules/node/node.js b/core/modules/node/node.js
index 98af6fd..086263d 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 22c93ac..59947a2 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/NodeType.php b/core/modules/node/src/Entity/NodeType.php
index 91d8a90..23f24a4 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 2828030..5a8af32 100644
--- a/core/modules/node/src/NodeForm.php
+++ b/core/modules/node/src/NodeForm.php
@@ -2,8 +2,9 @@
namespace Drupal\node;
-use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
+use Drupal\Core\Entity\Form\RevisionableContentEntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -11,7 +12,7 @@
/**
* Form handler for the node edit forms.
*/
-class NodeForm extends ContentEntityForm {
+class NodeForm extends RevisionableContentEntityForm {
/**
* The tempstore factory.
@@ -26,15 +27,15 @@ 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.
* @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* The factory for the temp store object.
*/
- public function __construct(EntityManagerInterface $entity_manager, PrivateTempStoreFactory $temp_store_factory) {
- parent::__construct($entity_manager);
+ public function __construct(EntityManagerInterface $entity_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, PrivateTempStoreFactory $temp_store_factory) {
+ parent::__construct($entity_manager, $entity_type_bundle_info);
$this->tempStoreFactory = $temp_store_factory;
}
@@ -44,6 +45,7 @@ public function __construct(EntityManagerInterface $entity_manager, PrivateTempS
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager'),
+ $container->get('entity_type.bundle.info'),
$container->get('user.private_tempstore')
);
}
@@ -51,19 +53,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}
- */
public function form(array $form, FormStateInterface $form_state) {
// Try to restore from temp store, this must be done before calling
// parent::form().
@@ -98,10 +87,6 @@ public function form(array $form, FormStateInterface $form_state) {
/** @var \Drupal\node\NodeInterface $node */
$node = $this->entity;
- if ($this->operation == 'edit') {
- $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.
@@ -110,47 +95,22 @@ public function form(array $form, FormStateInterface $form_state) {
'#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['advanced']['#attributes']['class'][] = 'entity-meta';
- $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']['#access'] = $current_user->hasPermission('administer nodes') && !$node->isNew();
- $form['revision_log'] += array(
- '#states' => array(
- 'visible' => array(
- ':input[name="revision"]' => array('checked' => TRUE),
- ),
- ),
- '#group' => 'revision_information',
- );
+ // Clear revision states, because it will conflicts with revision_log state.
+ $form['revision']['#states']['checked'] = [];
+
+ $form['revision_log'] += [
+ '#states' => [
+ 'visible' => [
+ ':input[name="revision"]' => ['checked' => TRUE],
+ ],
+ ],
+ ];
// Node author information for administrators.
$form['author'] = array(
@@ -304,32 +264,6 @@ protected function actions(array $form, FormStateInterface $form_state) {
}
/**
- * {@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.
*
* @param $form
diff --git a/core/modules/node/src/NodeTranslationHandler.php b/core/modules/node/src/NodeTranslationHandler.php
index 9c9741e..2f6d2ab 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 c034ffb..1aab64d 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.
@@ -28,7 +29,7 @@ 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 0f84d3d..47be4de 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;
@@ -123,6 +123,11 @@ public function testNormalize() {
array('value' => TRUE),
),
'non_rev_field' => array(),
+ 'revision_created' => array(
+ array('value' => $this->entity->getRevisionCreationTime()),
+ ),
+ 'revision_user' => array(),
+ 'revision_log_message' => array(),
'field_test_text' => array(
array(
'value' => $this->values['field_test_text']['value'],
@@ -192,6 +197,9 @@ public function testSerialize() {
'revision_id' => '' . $this->entity->getRevisionId() . '',
'default_langcode' => '1',
'non_rev_field' => '',
+ 'revision_created' => '' . $this->entity->getRevisionCreationTime() . '',
+ 'revision_user' => '',
+ 'revision_log_message' => '',
'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 0ee28bf..0dac588 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
@@ -12,7 +12,7 @@
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
* "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
* "form" = {
- * "default" = "Drupal\entity_test\EntityTestForm",
+ * "default" = "Drupal\entity_test\EntityTestRevisionForm",
* "delete" = "Drupal\entity_test\EntityTestDeleteForm"
* },
* "translation" = "Drupal\content_translation\ContentTranslationHandler",
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 47035ea..094f7e9 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;
/**
@@ -15,7 +17,7 @@
* "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
* "form" = {
- * "default" = "Drupal\entity_test\EntityTestForm",
+ * "default" = "\Drupal\entity_test\EntityTestRevisionForm",
* "delete" = "Drupal\entity_test\EntityTestDeleteForm"
* },
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
@@ -45,7 +47,9 @@
* }
* )
*/
-class EntityTestRev extends EntityTest {
+class EntityTestRev extends EntityTest implements RevisionLogInterface {
+
+ use RevisionLogEntityTrait;
/**
* {@inheritdoc}
@@ -53,13 +57,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/system/tests/modules/entity_test/src/EntityTestRevisionForm.php b/core/modules/system/tests/modules/entity_test/src/EntityTestRevisionForm.php
new file mode 100644
index 0000000..b0843c1
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test/src/EntityTestRevisionForm.php
@@ -0,0 +1,38 @@
+entity->name->value)) {
+ // Assign a random name to new EntityTest entities, to avoid repetition in
+ // tests.
+ $random = new Random();
+ $this->entity->name->value = $random->name();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(array $form, FormStateInterface $form_state) {
+ try {
+ parent::save($form, $form_state);
+ }
+ catch (\Exception $e) {
+ \Drupal::state()->set('entity_test.form.save.exception', get_class($e) . ': ' . $e->getMessage());
+ }
+ }
+
+}
diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
index 60ba8e5..acb84e5 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 23cf034..e49ee7e 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 56af888..5dc1a94 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)));