diff --git a/src/Entity/RevisionableEntityBundleInterface.php b/src/Entity/RevisionableEntityBundleInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..3aa705a66aeb2d4d4bfe3cd103405f40be112a22 --- /dev/null +++ b/src/Entity/RevisionableEntityBundleInterface.php @@ -0,0 +1,22 @@ +<?php + +/** + * @file + * Contains \Drupal\entity\Entity\RevisionableEntityBundleInterface. + */ + +namespace Drupal\entity\Entity; + +use Drupal\Core\Config\Entity\ConfigEntityInterface; + +interface RevisionableEntityBundleInterface extends ConfigEntityInterface { + + /** + * 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/src/Form/ContentEntityFormWithRevisions.php b/src/Form/ContentEntityFormWithRevisions.php new file mode 100644 index 0000000000000000000000000000000000000000..8ded451e070f266dc784ccd8957b5139ee9b6657 --- /dev/null +++ b/src/Form/ContentEntityFormWithRevisions.php @@ -0,0 +1,151 @@ +<?php + +/** + * @file + * Contains \Drupal\entity\Form\ContentEntityFormWithRevisions. + */ + +namespace Drupal\entity\Form; + +use Drupal\Core\Entity\ContentEntityForm; +use Drupal\Core\Form\FormStateInterface; +use Drupal\entity\Entity\RevisionableEntityBundleInterface; + +class ContentEntityFormWithRevisions extends ContentEntityForm { + + /** + * The entity being used by this form. + * + * @var \Drupal\Core\Entity\EntityInterface|\Drupal\Core\Entity\RevisionableInterface|\Drupal\entity\Revision\EntityRevisionLogInterface + */ + protected $entity; + + /** + * {@inheritdoc} + */ + protected function prepareEntity() { + parent::prepareEntity(); + + $bundle_entity = $this->getBundleEntity(); + + // Set up default values, if required. + if (!$this->entity->isNew()) { + $this->entity->setRevisionLogMessage(NULL); + } + + if ($bundle_entity instanceof RevisionableEntityBundleInterface) { + // Always use the default revision setting. + $this->entity->setNewRevision($bundle_entity && $bundle_entity->shouldCreateNewRevision()); + } + } + + protected function getBundleEntity() { + $bundle_entity = $this->entity->{$this->entity->getEntityType()->getKey('bundle')}->referencedEntities()[0]; + return $bundle_entity; + } + + /** + * {@inheritdoc} + */ + public function form(array $form, FormStateInterface $form_state) { + + $entity_type = $this->entity->getEntityType(); + + $bundle_entity = $this->getBundleEntity(); + + $account = $this->currentUser(); + + if ($this->operation == 'edit') { + $form['#title'] = $this->t('Edit %bundle_label @label', [ + '%bundle_label' => $bundle_entity ? $bundle_entity->label() : '', + '@label' => $this->entity->label(), + ]); + } + + $form['advanced'] = [ + '#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. + // @todo Could we autogenerate this form by using some widget on the + // revision info field. + $form['revision_information'] = [ + '#type' => 'details', + '#title' => $this->t('Revision information'), + // Open by default when "Create new revision" is checked. + '#open' => $this->entity->isNewRevision(), + '#group' => 'advanced', + '#weight' => 20, + '#access' => $this->entity->isNewRevision() || $account->hasPermission($entity_type->get('admin_permission')), + ]; + + $form['revision_information']['revision'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Create new revision'), + '#default_value' => $this->entity->isNewRevision(), + '#access' => $account->hasPermission($entity_type->get('admin_permission')), + ]; + + // 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 (!$this->entity->isNewRevision()) { + $form['revision_information']['revision']['#states'] = [ + 'checked' => [ + 'textarea[name="revision_log"]' => ['empty' => FALSE], + ], + ]; + } + + $form['revision_information']['revision_log'] = [ + '#type' => 'textarea', + '#title' => $this->t('Revision log message'), + '#rows' => 4, + '#default_value' => $this->entity->getRevisionLogMessage(), + '#description' => $this->t('Briefly describe the changes you have made.'), + ]; + + return parent::form($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + // Save as a new revision if requested to do so. + if (!$form_state->isValueEmpty('revision')) { + $this->entity->setNewRevision(); + } + + $insert = $this->entity->isNew(); + $this->entity->save(); + $context = ['@type' => $this->entity->bundle(), '%info' => $this->entity->label()]; + $logger = $this->logger($this->entity->id()); + $bundle_entity = $this->getBundleEntity(); + $t_args = ['@type' => $bundle_entity ? $bundle_entity->label() : 'None', '%info' => $this->entity->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)); + } + + if ($this->entity->id()) { + $form_state->setValue('id', $this->entity->id()); + $form_state->set('id', $this->entity->id()); + $form_state->setRedirectUrl($this->entity->urlInfo('collection')); + } + else { + // In the unlikely case something went wrong on save, the entity will be + // rebuilt and entity form redisplayed. + drupal_set_message($this->t('The entity could not be saved.'), 'error'); + $form_state->setRebuild(); + } + } + +}