summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2016-12-13 15:45:12 +0000
committerNathaniel Catchpole2016-12-13 15:45:12 +0000
commitf4a242f15463637805c3392c3eedf6f2b714923c (patch)
treedd5c944979d6c298b28ead5f57b8ac5bd5d593a0
parent0f139055718b608edfac1422e89667c7a7bf172a (diff)
Issue #2669802 by chr.fritsch, Berdir, seanB, bojanz, dawehner, yoroy, slashrsm, tstoeckler: Add a content entity form which allows to set revisions
-rw-r--r--core/core.libraries.yml7
-rw-r--r--core/lib/Drupal/Core/Entity/ContentEntityForm.php166
-rw-r--r--core/lib/Drupal/Core/Entity/EntityType.php14
-rw-r--r--core/lib/Drupal/Core/Entity/EntityTypeInterface.php8
-rw-r--r--core/lib/Drupal/Core/Entity/RevisionableEntityBundleInterface.php20
-rw-r--r--core/misc/entity-form.js (renamed from core/modules/block_content/js/block_content.js)10
-rw-r--r--core/modules/block_content/block_content.libraries.yml9
-rw-r--r--core/modules/block_content/src/BlockContentForm.php140
-rw-r--r--core/modules/block_content/src/BlockContentTranslationHandler.php18
-rw-r--r--core/modules/block_content/src/BlockContentTypeInterface.php11
-rw-r--r--core/modules/block_content/src/Entity/BlockContent.php10
-rw-r--r--core/modules/content_translation/src/ContentTranslationHandler.php10
-rw-r--r--core/modules/menu_link_content/src/Form/MenuLinkContentForm.php2
-rw-r--r--core/modules/node/node.js31
-rw-r--r--core/modules/node/node.libraries.yml4
-rw-r--r--core/modules/node/src/Entity/Node.php1
-rw-r--r--core/modules/node/src/Entity/NodeType.php7
-rw-r--r--core/modules/node/src/NodeForm.php83
-rw-r--r--core/modules/node/src/NodeTranslationHandler.php10
-rw-r--r--core/modules/node/src/NodeTypeInterface.php9
-rw-r--r--core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php23
-rw-r--r--core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php1
-rw-r--r--core/modules/system/tests/modules/entity_test/src/Entity/EntityTestRev.php14
-rw-r--r--core/modules/views/tests/src/Unit/EntityViewsDataTest.php15
-rw-r--r--core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php5
-rw-r--r--core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php7
26 files changed, 321 insertions, 314 deletions
diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index ce12db5..38e963e 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 29b0a9b..e131e9b 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;
@@ -22,13 +23,41 @@ 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 @@ class ContentEntityForm extends EntityForm implements ContentEntityFormInterface
*/
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 @@ class ContentEntityForm extends EntityForm implements ContentEntityFormInterface
$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 @@ class ContentEntityForm extends EntityForm implements ContentEntityFormInterface
// 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 @@ class ContentEntityForm extends EntityForm implements ContentEntityFormInterface
*/
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 89b83cf..78fb2ff 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -175,6 +175,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.
*
* @var string
@@ -692,6 +699,13 @@ class EntityType implements EntityTypeInterface {
/**
* {@inheritdoc}
*/
+ public function showRevisionUi() {
+ return $this->isRevisionable() && $this->show_revision_ui;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function isTranslatable() {
return !empty($this->translatable);
}
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index c6336c9..60d60b5 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -574,6 +574,14 @@ interface EntityTypeInterface extends PluginDefinitionInterface {
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.
*
* @return bool
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 @@
+<?php
+
+namespace Drupal\Core\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityInterface;
+
+/**
+ * Provides an interface defining a revisionable entity bundle.
+ */
+interface RevisionableEntityBundleInterface extends ConfigEntityInterface {
+
+ /**
+ * Gets 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/js/block_content.js b/core/misc/entity-form.js
index bbc0533..f86c416 100644
--- a/core/modules/block_content/js/block_content.js
+++ b/core/misc/entity-form.js
@@ -8,20 +8,20 @@
'use strict';
/**
- * Sets summaries about revision and translation of block content.
+ * Sets summaries about revision and translation of entities.
*
* @type {Drupal~behavior}
*
* @prop {Drupal~behaviorAttach} attach
- * Attaches summary behaviour block content form tabs.
+ * Attaches summary behaviour entity form tabs.
*
* Specifically, it updates summaries to the revision information and the
* translation options.
*/
- Drupal.behaviors.blockContentDetailsSummaries = {
+ Drupal.behaviors.entityContentDetailsSummaries = {
attach: function (context) {
var $context = $(context);
- $context.find('.block-content-form-revision-information').drupalSetSummary(function (context) {
+ $context.find('.entity-content-form-revision-information').drupalSetSummary(function (context) {
var $revisionContext = $(context);
var revisionCheckbox = $revisionContext.find('.js-form-item-revision input');
@@ -36,7 +36,7 @@
return Drupal.t('No revision');
});
- $context.find('fieldset.block-content-translation-options').drupalSetSummary(function (context) {
+ $context.find('details.entity-translation-options').drupalSetSummary(function (context) {
var $translationContext = $(context);
var translate;
var $checkbox = $translationContext.find('.js-form-item-translation-translate input');
diff --git a/core/modules/block_content/block_content.libraries.yml b/core/modules/block_content/block_content.libraries.yml
index 5a1b5b6..b9549d4 100644
--- a/core/modules/block_content/block_content.libraries.yml
+++ b/core/modules/block_content/block_content.libraries.yml
@@ -1,8 +1,7 @@
+# Deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
+# This is just for BC and not used anymore. See https://www.drupal.org/node/2669802
drupal.block_content:
version: VERSION
- js:
- js/block_content.js: {}
+ js: {}
dependencies:
- - core/jquery
- - core/drupal
- - core/drupal.form
+ - core/drupal.entity-form
diff --git a/core/modules/block_content/src/BlockContentForm.php b/core/modules/block_content/src/BlockContentForm.php
index 8815f56..b3f50f7 100644
--- a/core/modules/block_content/src/BlockContentForm.php
+++ b/core/modules/block_content/src/BlockContentForm.php
@@ -4,11 +4,7 @@ namespace Drupal\block_content;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\ContentEntityForm;
-use Drupal\Core\Entity\EntityManagerInterface;
-use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Language\LanguageManagerInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Form handler for the custom block edit forms.
@@ -16,27 +12,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
class BlockContentForm extends ContentEntityForm {
/**
- * The custom block storage.
- *
- * @var \Drupal\Core\Entity\EntityStorageInterface
- */
- protected $blockContentStorage;
-
- /**
- * The custom block type storage.
- *
- * @var \Drupal\Core\Entity\EntityStorageInterface
- */
- protected $blockContentTypeStorage;
-
- /**
- * The language manager.
- *
- * @var \Drupal\Core\Language\LanguageManagerInterface
- */
- protected $languageManager;
-
- /**
* The block content entity.
*
* @var \Drupal\block_content\BlockContentInterface
@@ -44,62 +19,12 @@ class BlockContentForm extends ContentEntityForm {
protected $entity;
/**
- * Constructs a BlockContentForm object.
- *
- * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
- * The entity manager.
- * @param \Drupal\Core\Entity\EntityStorageInterface $block_content_storage
- * The custom block storage.
- * @param \Drupal\Core\Entity\EntityStorageInterface $block_content_type_storage
- * The custom block type storage.
- * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
- * The language manager.
- */
- public function __construct(EntityManagerInterface $entity_manager, EntityStorageInterface $block_content_storage, EntityStorageInterface $block_content_type_storage, LanguageManagerInterface $language_manager) {
- parent::__construct($entity_manager);
- $this->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 @@ class BlockContentForm extends ContentEntityForm {
// 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 @@ class BlockContentForm extends ContentEntityForm {
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 781ba1b..b446cde 100644
--- a/core/modules/block_content/src/BlockContentTranslationHandler.php
+++ b/core/modules/block_content/src/BlockContentTranslationHandler.php
@@ -5,7 +5,6 @@ namespace Drupal\block_content;
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.
@@ -15,23 +14,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('<em>Edit @type</em> @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 @@ 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 13af342..51ae6f6 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -35,6 +35,7 @@ use Drupal\user\UserInterface;
* 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 @@ class BlockContent extends ContentEntityBase implements BlockContentInterface {
$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 @@ class ContentTranslationHandler implements ContentTranslationHandlerInterface, E
'#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 ed372a9..029ca49 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 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/Node.php b/core/modules/node/src/Entity/Node.php
index f034957..68afc83 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -46,6 +46,7 @@ use Drupal\user\UserInterface;
* 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 91d8a90..23f24a4 100644
--- a/core/modules/node/src/Entity/NodeType.php
+++ b/core/modules/node/src/Entity/NodeType.php
@@ -205,4 +205,11 @@ class NodeType extends ConfigEntityBundleBase implements NodeTypeInterface {
$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..4193923 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.
@@ -51,19 +51,6 @@ class NodeForm extends ContentEntityForm {
/**
* {@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().
@@ -102,55 +89,15 @@ class NodeForm extends ContentEntityForm {
$form['#title'] = $this->t('<em>Edit @type</em> @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(
@@ -304,32 +251,6 @@ class NodeForm extends ContentEntityForm {
}
/**
- * {@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..df4831e 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 @@ interface NodeTypeInterface extends ConfigEntityInterface {
*
* @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 0f84d3d..2f5c20a 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 @@ class EntitySerializationTest extends NormalizerTestBase {
'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 @@ class EntitySerializationTest extends NormalizerTestBase {
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 @@ class EntitySerializationTest extends NormalizerTestBase {
'revision_id' => '<revision_id><value>' . $this->entity->getRevisionId() . '</value></revision_id>',
'default_langcode' => '<default_langcode><value>1</value></default_langcode>',
'non_rev_field' => '<non_rev_field/>',
+ 'revision_created' => '<revision_created><value>' . $this->entity->getRevisionCreationTime() . '</value></revision_created>',
+ 'revision_user' => '<revision_user><target_id>' . $this->user->id() . '</target_id><target_type>' . $this->user->getEntityTypeId() . '</target_type><target_uuid>' . $this->user->uuid() . '</target_uuid><url>' . $this->user->url() . '</url></revision_user>',
+ 'revision_log_message' => '<revision_log_message><value>' . $this->values['revision_log_message']['value'] . '</value></revision_log_message>',
'field_test_text' => '<field_test_text><value>' . $this->values['field_test_text']['value'] . '</value><format>' . $this->values['field_test_text']['format'] . '</format></field_test_text>',
);
// 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..f01675f 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 @@ namespace Drupal\entity_test\Entity;
* 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 47035ea..49c5aca 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 @@ use Drupal\Core\Field\BaseFieldDefinition;
* 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 @@ use Drupal\Core\Field\BaseFieldDefinition;
* }
* )
*/
-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 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 @@ class EntityViewsDataTest extends UnitTestCase {
$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 @@ if (!function_exists('t')) {
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 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase {
$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 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase {
/**
* 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 @@ class EntityFieldTest extends EntityKernelTestBase {
// 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)));