Commit f724db34 authored by webchick's avatar webchick

Issue #2936793 by tim.plunkett, tstoeckler, EclipseGc:...

Issue #2936793 by tim.plunkett, tstoeckler, EclipseGc: EntityReferenceItem::generateSampleValue() should create a sample entity if a referenceable entity is not found
parent c5c96bf3
......@@ -4,6 +4,7 @@
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\ContentEntityStorageInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
......@@ -296,6 +297,37 @@ public static function generateSampleValue(FieldDefinitionInterface $field_defin
$values['target_id'] = array_rand($referenceable[$group]);
return $values;
}
// Attempt to create a sample entity, avoiding recursion.
$entity_storage = \Drupal::entityTypeManager()->getStorage($options['target_type']);
if ($options['target_type'] !== $field_definition->getTargetEntityTypeId() && $entity_storage instanceof ContentEntityStorageInterface) {
$bundle = static::getRandomBundle($entity_type, $options['handler_settings']);
$values['entity'] = $entity_storage->createWithSampleValues($bundle);
return $values;
}
}
/**
* Gets a bundle for a given entity type and selection options.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
* @param array $selection_settings
* An array of selection settings.
*
* @return string|null
* Either the bundle string, or NULL if there is no bundle.
*/
protected static function getRandomBundle(EntityTypeInterface $entity_type, array $selection_settings) {
if ($bundle_key = $entity_type->getKey('bundle')) {
if (!empty($selection_settings['target_bundles'])) {
$bundle_ids = $selection_settings['target_bundles'];
}
else {
$bundle_ids = \Drupal::service('entity_type.bundle.info')->getBundleInfo($entity_type->id());
}
return array_rand($bundle_ids);
}
}
/**
......
......@@ -2,6 +2,7 @@
namespace Drupal\Core\Field\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Language\LanguageInterface;
......@@ -117,4 +118,20 @@ public function onChange($property_name, $notify = TRUE) {
parent::onChange($property_name, $notify);
}
/**
* {@inheritdoc}
*/
public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
// Defer to the callback in the item definition as it can be overridden.
$constraint = $field_definition->getItemDefinition()->getConstraint('ComplexData');
if (isset($constraint['value']['AllowedValues']['callback'])) {
$languages = $constraint['value']['AllowedValues']['callback']();
}
else {
$languages = static::getAllowedLanguageCodes();
}
$values['value'] = $languages[array_rand($languages)];
return $values;
}
}
......@@ -2,7 +2,6 @@
namespace Drupal\Tests\aggregator\Kernel\Migrate;
use Drupal\migrate\MigrateException;
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
use Drupal\migrate_drupal\Tests\StubTestTrait;
......@@ -40,18 +39,6 @@ public function testFeedStub() {
* Tests creation of aggregator feed items.
*/
public function testItemStub() {
try {
// We expect an exception, because there's no feed to reference.
$this->performStubTest('aggregator_item');
$this->fail('Expected exception has not been thrown.');
}
catch (MigrateException $e) {
$this->assertIdentical($e->getMessage(),
'Stubbing failed, unable to generate value for field fid');
}
// The stub should pass when there's a feed to point to.
$this->createStub('aggregator_feed');
$this->performStubTest('aggregator_item');
}
......
......@@ -3,7 +3,6 @@
namespace Drupal\Tests\comment\Kernel\Migrate;
use Drupal\comment\Entity\CommentType;
use Drupal\migrate\MigrateException;
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
use Drupal\migrate_drupal\Tests\StubTestTrait;
use Drupal\node\Entity\NodeType;
......@@ -29,6 +28,8 @@ protected function setUp() {
parent::setUp();
$this->installEntitySchema('comment');
$this->installEntitySchema('node');
$this->installSchema('system', ['sequences']);
// Make sure uid 0 is created (default uid for comments is 0).
$storage = \Drupal::entityManager()->getStorage('user');
// Insert a row for the anonymous user.
......@@ -55,18 +56,6 @@ protected function setUp() {
* Tests creation of comment stubs.
*/
public function testStub() {
try {
// We expect an exception, because there's no node to reference.
$this->performStubTest('comment');
$this->fail('Expected exception has not been thrown.');
}
catch (MigrateException $e) {
$this->assertIdentical($e->getMessage(),
'Stubbing failed, unable to generate value for field entity_id');
}
// The stub should pass when there's a node to point to.
$this->createStub('node');
$this->performStubTest('comment');
}
......
......@@ -16,6 +16,7 @@
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\node\NodeInterface;
use Drupal\taxonomy\TermInterface;
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
use Drupal\file\Entity\File;
use Drupal\node\Entity\Node;
......@@ -193,6 +194,24 @@ public function testContentEntityReferenceItem() {
$entity = EntityTest::create(['user_id' => ['target_id' => (int) $user->id(), 'entity' => $user]]);
}
/**
* Tests the ::generateSampleValue() method.
*/
public function testGenerateSampleValue() {
$entity = EntityTest::create();
// Test while a term exists.
$entity->field_test_taxonomy_term->generateSampleItems();
$this->assertInstanceOf(TermInterface::class, $entity->field_test_taxonomy_term->entity);
$this->entityValidateAndSave($entity);
// Delete the term and test again.
$this->term->delete();
$entity->field_test_taxonomy_term->generateSampleItems();
$this->assertInstanceOf(TermInterface::class, $entity->field_test_taxonomy_term->entity);
$this->entityValidateAndSave($entity);
}
/**
* Tests referencing content entities with string IDs.
*/
......
......@@ -9,6 +9,7 @@
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Language\LanguageInterface;
use Drupal\user\RoleInterface;
use Drupal\user\StatusItem;
use Drupal\user\TimeZoneItem;
use Drupal\user\UserInterface;
......@@ -505,6 +506,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
->setLabel(t('User status'))
->setDescription(t('Whether the user is active or blocked.'))
->setDefaultValue(FALSE);
$fields['status']->getItemDefinition()->setClass(StatusItem::class);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
......
<?php
namespace Drupal\user;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\BooleanItem;
/**
* Defines the 'status' entity field type.
*
* @todo Consider making this a full field type plugin in
* https://www.drupal.org/project/drupal/issues/2936864.
*/
class StatusItem extends BooleanItem {
/**
* {@inheritdoc}
*/
public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
// Always generate a sample with an enabled status.
$values['value'] = 1;
return $values;
}
}
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