Commit a63671be authored by RoSk0's avatar RoSk0

Issue #2926663 by RoSk0: Improve revision handling.

parent 0f81027e
......@@ -3,7 +3,7 @@
namespace Drupal\crm_core_activity;
use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
use Drupal\entity\Entity\RevisionableEntityBundleInterface;
use Drupal\Core\Entity\RevisionableEntityBundleInterface;
/**
* Defines methods for CRM ActivityType entities.
......
......@@ -33,6 +33,7 @@ use Drupal\entity\Revision\RevisionableContentEntityBase;
* "revision" = "\Drupal\entity\Routing\RevisionRouteProvider",
* },
* },
* show_revision_ui = TRUE,
* base_table = "crm_core_activity",
* revision_table = "crm_core_activity_revision",
* admin_permission = "administer crm_core_activity entities",
......@@ -94,25 +95,25 @@ class Activity extends RevisionableContentEntityBase implements ActivityInterfac
->setRevisionable(TRUE)
->setSetting('default_value', '')
->setSetting('max_length', 255)
->setDisplayOptions('view', array(
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => -5,
))
->setDisplayOptions('form', array(
])
->setDisplayOptions('form', [
'type' => 'text_textfield',
'weight' => -5,
))
])
->setDisplayConfigurable('form', TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time that the activity was created.'))
->setRevisionable(TRUE)
->setDisplayOptions('form', array(
->setDisplayOptions('form', [
'type' => 'datetime_timestamp',
'weight' => -5,
))
])
->setDisplayConfigurable('form', TRUE);
$fields['changed'] = BaseFieldDefinition::create('changed')
......
<?php
/**
* @file
* Contains \Drupal\crm_core_activity\Entity\ActivityType.
*/
namespace Drupal\crm_core_activity\Entity;
......@@ -130,7 +126,7 @@ class ActivityType extends ConfigEntityBundleBase implements ActivityTypeInterfa
public static function preDelete(EntityStorageInterface $storage, array $entities) {
parent::preDelete($storage, $entities);
$ids = array_map(function(EntityInterface $entity){
$ids = array_map(function (EntityInterface $entity) {
return $entity->id();
}, $entities);
......@@ -143,7 +139,7 @@ class ActivityType extends ConfigEntityBundleBase implements ActivityTypeInterfa
$activities = Activity::loadMultiple($results);
\Drupal::entityTypeManager()->getStorage('crm_core_activity')->delete($activities);
// @todo Handle singular and plural.
\Drupal::logger('crm_core_activity')->info('Delete !count activities due to deletion of activity type.', array('!count' => count($results)));
\Drupal::logger('crm_core_activity')->info('Delete !count activities due to deletion of activity type.', ['!count' => count($results)]);
}
}
......
<?php
/**
* @file
* Contains \Drupal\crm_core_activity\Form\ActivityForm.
*/
namespace Drupal\crm_core_activity\Form;
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\entity\Form\RevisionableContentEntityForm;
/**
* Class ActivityForm.
*/
class ActivityForm extends RevisionableContentEntityForm {
class ActivityForm extends ContentEntityForm {
/**
* {@inheritdoc}
......@@ -23,7 +18,7 @@ class ActivityForm extends RevisionableContentEntityForm {
$status = $activity->save();
$t_args = array('%title' => $activity->label(), 'link' => $activity->url());
$t_args = ['%title' => $activity->label(), 'link' => $activity->url()];
if ($status == SAVED_UPDATED) {
drupal_set_message($this->t('Activity %title edited.', $t_args));
......
......@@ -10,6 +10,9 @@ revert individual record:
revert organization revisions:
title: 'Revert organization revisions'
description: 'Allows the user to have ability to revert organizations'
view all crm_core_individual revisions:
title: 'View all crm_core_individual revisions'
'restrict access': TRUE
view all crm_core_organization revisions:
title: 'View all crm_core_organization revisions'
'restrict access': TRUE
......
......@@ -2,7 +2,6 @@
namespace Drupal\crm_core_contact\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
......@@ -11,6 +10,7 @@ use Drupal\crm_core\EntityOwnerTrait;
use Drupal\crm_core_activity\Entity\Activity;
use Drupal\crm_core_contact\IndividualInterface;
use Drupal\field\FieldStorageConfigInterface;
use Drupal\entity\Revision\RevisionableContentEntityBase;
/**
* CRM Individual Entity Class.
......@@ -30,8 +30,11 @@ use Drupal\field\FieldStorageConfigInterface;
* "views_data" = "Drupal\views\EntityViewsData",
* "route_provider" = {
* "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
* "revision" = "\Drupal\entity\Routing\RevisionRouteProvider",
* },
* },
* show_revision_ui = TRUE,
* admin_permission = "administer crm_core_individual entities",
* base_table = "crm_core_individual",
* revision_table = "crm_core_individual_revision",
* entity_keys = {
......@@ -39,6 +42,7 @@ use Drupal\field\FieldStorageConfigInterface;
* "revision" = "revision_id",
* "bundle" = "type",
* "uuid" = "uuid",
* "langcode" = "langcode",
* },
* bundle_entity_type = "crm_core_individual_type",
* field_ui_base_route = "entity.crm_core_individual_type.edit_form",
......@@ -53,11 +57,14 @@ use Drupal\field\FieldStorageConfigInterface;
* "canonical" = "/crm-core/individual/{crm_core_individual}",
* "collection" = "/crm-core/individual",
* "edit-form" = "/crm-core/individual/{crm_core_individual}/edit",
* "delete-form" = "/crm-core/individual/{crm_core_individual}/delete"
* "delete-form" = "/crm-core/individual/{crm_core_individual}/delete",
* "revision" = "/crm-core/individual/{crm_core_individual}/revisions/{crm_core_individual_revision}/view",
* "revision-revert-form" = "/crm-core/individual/{crm_core_individual}/revisions/{crm_core_individual_revision}/revert",
* "version-history" = "/crm-core/individual/{crm_core_individual}/revisions",
* }
* )
*/
class Individual extends ContentEntityBase implements IndividualInterface {
class Individual extends RevisionableContentEntityBase implements IndividualInterface {
use EntityChangedTrait;
use EntityOwnerTrait;
......@@ -72,10 +79,10 @@ class Individual extends ContentEntityBase implements IndividualInterface {
->setLabel(t('Created'))
->setDescription(t('The time that the individual was created.'))
->setRevisionable(TRUE)
->setDisplayOptions('form', array(
->setDisplayOptions('form', [
'type' => 'datetime_timestamp',
'weight' => -5,
))
])
->setDisplayConfigurable('form', TRUE);
$fields['changed'] = BaseFieldDefinition::create('changed')
......@@ -89,6 +96,7 @@ class Individual extends ContentEntityBase implements IndividualInterface {
$fields['name'] = BaseFieldDefinition::create('name')
->setLabel(t('Name'))
->setDescription(t('Name of the individual.'))
->setRevisionable(TRUE)
->setDisplayOptions('form', [
'type' => 'name_default',
'weight' => 0,
......@@ -119,6 +127,7 @@ class Individual extends ContentEntityBase implements IndividualInterface {
$fields['birth_date'] = BaseFieldDefinition::create('datetime')
->setLabel(t('Birth date'))
->setDescription(t('Birth date of the individual.'))
->setRevisionable(TRUE)
->setSetting('datetime_type', ['datetime_type' => 'date'])
->setDisplayOptions('form', [
'type' => 'datetime_datelist',
......@@ -128,6 +137,7 @@ class Individual extends ContentEntityBase implements IndividualInterface {
$fields['email'] = BaseFieldDefinition::create('email_with_type')
->setLabel(t('Email'))
->setDescription(t('Email of the individual.'))
->setRevisionable(TRUE)
->setCardinality(FieldStorageConfigInterface::CARDINALITY_UNLIMITED)
->setSetting('email_types', [
'private' => t('Private'),
......@@ -138,19 +148,6 @@ class Individual extends ContentEntityBase implements IndividualInterface {
'weight' => 3,
]);
$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)
->setTranslatable(TRUE)
->setDisplayOptions('form', array(
'type' => 'text_textarea',
'weight' => 25,
'settings' => array(
'rows' => 4,
),
));
return $fields;
}
......@@ -220,10 +217,6 @@ class Individual extends ContentEntityBase implements IndividualInterface {
public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) {
parent::preSaveRevision($storage, $record);
if (!isset($record->revision_log)) {
$record->revision_log = '';
}
$account = \Drupal::currentUser();
$record->uid = $account->id();
}
......@@ -246,7 +239,7 @@ class Individual extends ContentEntityBase implements IndividualInterface {
// Load fully populated Activity objects to analyze/update.
$crm_core_activities = Activity::loadMultiple($activity_ids);
$activities_to_remove = array();
$activities_to_remove = [];
foreach ($crm_core_activities as $crm_core_activity) {
/** @var \Drupal\crm_core_activity\Entity\Activity $crm_core_activity */
......
......@@ -4,9 +4,9 @@ namespace Drupal\crm_core_contact\Entity;
use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
use Drupal\Core\Entity\EntityDescriptionInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\crm_core_contact\ContactTypeInterface;
use Drupal\Core\Entity\RevisionableEntityBundleInterface;
/**
* CRM Individual Type Entity Class.
......@@ -46,7 +46,7 @@ use Drupal\crm_core_contact\ContactTypeInterface;
* }
* )
*/
class IndividualType extends ConfigEntityBundleBase implements ContactTypeInterface, EntityDescriptionInterface {
class IndividualType extends ConfigEntityBundleBase implements ContactTypeInterface, EntityDescriptionInterface, RevisionableEntityBundleInterface {
/**
* The machine-readable name of this type.
......@@ -75,7 +75,7 @@ class IndividualType extends ConfigEntityBundleBase implements ContactTypeInterf
* A boolean indicating whether this type is locked or not, locked individual
* type cannot be edited or disabled/deleted.
*
* @var boolean
* @var bool
*/
public $locked;
......@@ -89,6 +89,13 @@ class IndividualType extends ConfigEntityBundleBase implements ContactTypeInterf
*/
public $primary_fields;
/**
* Should new entities of this bundle have a new revision by default.
*
* @var bool
*/
protected $new_revision = TRUE;
/**
* {@inheritdoc}
*/
......@@ -103,9 +110,9 @@ class IndividualType extends ConfigEntityBundleBase implements ContactTypeInterf
parent::preCreate($storage, $values);
// Ensure default values are set.
$values += array(
$values += [
'locked' => FALSE,
);
];
}
/**
......@@ -134,4 +141,11 @@ class IndividualType extends ConfigEntityBundleBase implements ContactTypeInterf
return $this;
}
/**
* {@inheritdoc}
*/
public function shouldCreateNewRevision() {
return $this->new_revision;
}
}
......@@ -34,6 +34,7 @@ use Drupal\entity\Revision\RevisionableContentEntityBase;
* base_table = "crm_core_organization",
* revision_table = "crm_core_organization_revision",
* admin_permission = "administer crm_core_organization entities",
* show_revision_ui = TRUE,
* entity_keys = {
* "id" = "organization_id",
* "revision" = "revision_id",
......@@ -76,10 +77,10 @@ class Organization extends RevisionableContentEntityBase implements ContactInter
->setLabel(t('Created'))
->setDescription(t('The time that the organization was created.'))
->setRevisionable(TRUE)
->setDisplayOptions('form', array(
->setDisplayOptions('form', [
'type' => 'datetime_timestamp',
'weight' => -5,
))
])
->setDisplayConfigurable('form', TRUE);
$fields['changed'] = BaseFieldDefinition::create('changed')
......@@ -93,15 +94,15 @@ class Organization extends RevisionableContentEntityBase implements ContactInter
$fields['name'] = BaseFieldDefinition::create('string')
->setLabel(t('Name'))
->setRevisionable(TRUE)
->setDisplayOptions('form', array(
->setDisplayOptions('form', [
'type' => 'text_textfield',
'weight' => 0,
))
->setDisplayOptions('view', array(
])
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => 0,
))
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
......@@ -129,7 +130,7 @@ class Organization extends RevisionableContentEntityBase implements ContactInter
// Load fully populated Activity objects to analyze/update.
$crm_core_activities = $crm_core_activity_storage->loadMultiple($activity_ids);
$activities_to_remove = array();
$activities_to_remove = [];
foreach ($crm_core_activities as $crm_core_activity) {
/** @var \Drupal\crm_core_activity\Entity\Activity $crm_core_activity */
......
......@@ -5,8 +5,8 @@ namespace Drupal\crm_core_contact\Entity;
use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
use Drupal\Core\Entity\EntityDescriptionInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\RevisionableEntityBundleInterface;
use Drupal\crm_core_contact\ContactTypeInterface;
use Drupal\entity\Entity\RevisionableEntityBundleInterface;
/**
* CRM Organization Type Entity Class.
......@@ -75,7 +75,7 @@ class OrganizationType extends ConfigEntityBundleBase implements ContactTypeInte
* A boolean indicating whether this type is locked or not, locked contact
* type cannot be edited or disabled/deleted.
*
* @var boolean
* @var bool
*/
protected $locked;
......@@ -110,9 +110,9 @@ class OrganizationType extends ConfigEntityBundleBase implements ContactTypeInte
parent::preCreate($storage, $values);
// Ensure default values are set.
$values += array(
$values += [
'locked' => FALSE,
);
];
}
/**
......@@ -157,4 +157,5 @@ class OrganizationType extends ConfigEntityBundleBase implements ContactTypeInte
public function shouldCreateNewRevision() {
return $this->new_revision;
}
}
......@@ -2,8 +2,8 @@
namespace Drupal\crm_core_contact\Form;
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\entity\Form\RevisionableContentEntityForm;
/**
* Class OrganizationForm.
......@@ -12,7 +12,7 @@ use Drupal\entity\Form\RevisionableContentEntityForm;
*
* @package Drupal\crm_core_contact\Form
*/
class OrganizationForm extends RevisionableContentEntityForm {
class OrganizationForm extends ContentEntityForm {
/**
* {@inheritdoc}
......@@ -43,9 +43,9 @@ class OrganizationForm extends RevisionableContentEntityForm {
*/
protected function actions(array $form, FormStateInterface $form_state) {
$actions = parent::actions($form, $form_state);
$actions['submit']['#value'] = $this->t('Save @organization_type', array(
$actions['submit']['#value'] = $this->t('Save @organization_type', [
'@organization_type' => $this->entity->get('type')->entity->label(),
));
]);
return $actions;
}
......
......@@ -24,62 +24,62 @@ class OrganizationTypeForm extends BundleEntityFormBase {
/* @var \Drupal\crm_core_contact\Entity\OrganizationType $type */
$type = $this->entity;
$form['label'] = array(
$form['label'] = [
'#title' => $this->t('Name'),
'#type' => 'textfield',
'#default_value' => $type->label(),
'#description' => $this->t('The human-readable name of this organization type. It is recommended that this name begin with a capital letter and contain only letters, numbers, and spaces. This name must be unique.'),
'#required' => TRUE,
'#size' => 32,
);
];
$form['id'] = array(
$form['id'] = [
'#type' => 'machine_name',
'#default_value' => $type->id(),
'#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
'#machine_name' => array(
'#machine_name' => [
'exists' => 'Drupal\crm_core_contact\Entity\OrganizationType::load',
'source' => array('name'),
),
'source' => ['label'],
],
'#description' => $this->t('A unique machine-readable name for this organization type. It must only contain lowercase letters, numbers, and underscores.'),
);
];
$form['description'] = array(
$form['description'] = [
'#title' => $this->t('Description'),
'#type' => 'textarea',
'#default_value' => $type->getDescription(),
'#description' => $this->t('Describe this organization type.'),
);
];
// Primary fields section.
$form['primary_fields_container'] = array(
$form['primary_fields_container'] = [
'#type' => 'fieldset',
'#title' => $this->t('Primary Fields'),
'#description' => $this->t('Primary fields are used to tell other modules what fields to use for common communications tasks such as sending an email, addressing an envelope, etc. Use the fields below to indicate the primary fields for this organization type.'),
);
];
// @todo Move primary fields array to some hook. This Would allow extend this
// list to other modules. This hook should return array('key'=>t('Name')).
$primary_fields = array('email', 'address', 'phone');
$options = array();
$primary_fields = ['email', 'address', 'phone'];
$options = [];
$type_id = $type->id();
if (isset($type_id)) {
/* @var \Drupal\Core\Field\FieldDefinitionInterface[] $instances */
$instances = \Drupal::service('entity_field.manager')->getFieldDefinitions('crm_core_organization', $type_id);
$instances = isset($instances[$type_id]) ? $instances[$type_id] : array();
$instances = isset($instances[$type_id]) ? $instances[$type_id] : [];
foreach ($instances as $instance) {
$options[$instance->getName()] = $instance->getLabel();
}
}
foreach ($primary_fields as $primary_field) {
$form['primary_fields_container'][$primary_field] = array(
$form['primary_fields_container'][$primary_field] = [
'#type' => 'select',
'#title' => $this->t('Primary @field field', array('@field' => $primary_field)),
'#title' => $this->t('Primary @field field', ['@field' => $primary_field]),
'#default_value' => empty($type->getPrimaryFields()[$primary_field]) ? '' : $type->getPrimaryFields()[$primary_field],
'#empty_value' => '',
'#empty_option' => $this->t('--Please Select--'),
'#options' => $options,
);
];
}
return $this->protectBundleIdElement($form);
......@@ -103,7 +103,7 @@ class OrganizationTypeForm extends BundleEntityFormBase {
$id = trim($form_state->getValue('id'));
// '0' is invalid, since elsewhere we check it using empty().
if ($id == '0') {
$form_state->setErrorByName('id', $this->t("Invalid machine-readable name. Enter a name other than %invalid.", array('%invalid' => $id)));
$form_state->setErrorByName('id', $this->t("Invalid machine-readable name. Enter a name other than %invalid.", ['%invalid' => $id]));
}
}
......
......@@ -307,6 +307,34 @@ class IndividualUiTest extends WebTestBase {
$this->assertText(t('Name'), 'Name field is available on manage display.');
}
/**
* Test individual revisions.
*/
public function testIndividualRevisions() {
$user = $this->drupalCreateUser([
'administer crm_core_individual entities',
'view all crm_core_individual revisions',
]);
$this->drupalLogin($user);
$individual = ['name[0][given]' => 'rev', 'name[0][family]' => '1'];
$this->drupalPostForm('crm-core/individual/add/customer', $individual, 'Save Customer');
$individual_1 = ['name[0][family]' => '2'];
$this->drupalPostForm('crm-core/individual/1/edit', $individual_1, 'Save Customer');
$individual_2 = ['name[0][family]' => '3'];
$this->drupalPostForm('crm-core/individual/1/edit', $individual_2, 'Save Customer');
$this->clickLink('Revisions');
$this->assertLinkByHref('crm-core/individual/1');
$this->assertLinkByHref('crm-core/individual/1/revisions/1/view');
$this->assertLinkByHref('crm-core/individual/1/revisions/2/view');
$this->drupalGet('crm-core/individual/1/revisions/1/view');
$this->assertText('rev 1');
$this->drupalGet('crm-core/individual/1/revisions/2/view');
$this->assertText('rev 2');
}
/**
* Test list builder views for contact entities.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment