Merge branch 'farmOS:2.x' into AssetOwners

This commit is contained in:
jgOhYeah 2022-04-02 12:46:42 +11:00 committed by GitHub
commit 218ad1c476
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 365 additions and 153 deletions

View File

@ -7,9 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Fixed
- [Only require a name to build map popups #515](https://github.com/farmOS/farmOS/pull/515)
- [Issue #3269543 by paul121: Automatically remove prepopulated entities from quick forms](https://www.drupal.org/project/farm/issues/3269543)
- [Do not add views handlers for unsupported field types #512](https://github.com/farmOS/farmOS/pull/512)
- [Allow importing KML with empty geometries #510](https://github.com/farmOS/farmOS/issues/510)
### Security
- Update Drupal core to 9.3.8 for [SA-CORE-2022-005](https://www.drupal.org/sa-core-2022-005).
- Update Drupal core to 9.3.9 for [SA-CORE-2022-006](https://www.drupal.org/sa-core-2022-006).
## [2.0.0-beta3] 2022-03-03
### Added
- Document farmOS cron set-up: https://farmos.org/hosting/install#cron
- [Issue #3253433: Provide a helper function for loading flag options and allowed values](https://www.drupal.org/project/farm/issues/3253433)
### Changed
@ -23,6 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [Maps broken with Uncaught SyntaxError: Unexpected token '?' #501](https://github.com/farmOS/farmOS/issues/501)
- [Asset autocomplete breaks when asset has parentheses at the end #502](https://github.com/farmOS/farmOS/issues/502)
- [Issue #3265207: API keys directory failure prevents farm client creation](https://www.drupal.org/project/farm/issues/3265207)
- [Issue #3264564: No space rendered in field suffix](https://www.drupal.org/project/farm/issues/3264564)
- [Error: Call to a member function get() on null in ContentEntityGeometryNormalizer.php on line 64 #493](https://github.com/farmOS/farmOS/issues/493)
### Security
@ -143,6 +160,7 @@ moving forward.
Drupal 7, which required a complete refactor of the codebase. By comparison,
updating from Drupal 9 to 10 will simply involve updating deprecated code.
[Unreleased]: https://github.com/farmOS/farmOS/compare/2.0.0-beta2...HEAD
[Unreleased]: https://github.com/farmOS/farmOS/compare/2.0.0-beta3...HEAD
[2.0.0-beta3]: https://github.com/farmOS/farmOS/releases/tag/2.0.0-beta3
[2.0.0-beta2]: https://github.com/farmOS/farmOS/releases/tag/2.0.0-beta2
[2.0.0-beta1]: https://github.com/farmOS/farmOS/releases/tag/2.0.0-beta1

View File

@ -18,11 +18,11 @@
"require": {
"cweagans/composer-patches": "^1.6",
"drupal/admin_toolbar": "^2.4",
"drupal/core": "9.3.6",
"drupal/core": "9.3.9",
"drupal/config_update": "^1.7",
"drupal/csv_serialization": "^2.0",
"drupal/date_popup": "^1.1",
"drupal/entity": "1.2",
"drupal/entity": "1.3",
"drupal/entity_browser": "^2.6",
"drupal/entity_reference_integrity": "^1.1",
"drupal/entity_reference_revisions": "^1.8",

View File

@ -1,11 +1,11 @@
{
"require": {
"cweagans/composer-patches": "^1.7",
"drupal/core-composer-scaffold": "9.3.6"
"drupal/core-composer-scaffold": "9.3.9"
},
"require-dev": {
"brianium/paratest": "^4",
"drupal/core-dev": "9.3.6",
"drupal/core-dev": "9.3.9",
"phpspec/prophecy-phpunit": "^2",
"symfony/finder": "^4.0"
},

View File

@ -8,6 +8,22 @@
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
/**
* Land type options helper.
*
* @return array
* Returns an array of land types for use in form select options.
*/
function farm_land_type_options() {
/** @var \Drupal\farm_land\Entity\FarmLandTypeInterface[] $types */
$types = \Drupal::entityTypeManager()->getStorage('land_type')->loadMultiple();
$options = [];
foreach ($types as $id => $type) {
$options[$id] = $type->getLabel();
}
return $options;
}
/**
* Allowed values callback function for the land type field.
*
@ -22,11 +38,5 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface;
* Returns an array of allowed values for use in form select options.
*/
function farm_land_type_field_allowed_values(FieldStorageDefinitionInterface $definition, ContentEntityInterface $entity = NULL, bool &$cacheable = TRUE) {
/** @var \Drupal\farm_land\Entity\FarmLandTypeInterface[] $types */
$types = \Drupal::entityTypeManager()->getStorage('land_type')->loadMultiple();
$allowed_values = [];
foreach ($types as $id => $type) {
$allowed_values[$id] = $type->getLabel();
}
return $allowed_values;
return farm_land_type_options();
}

View File

@ -8,6 +8,22 @@
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
/**
* Structure type options helper.
*
* @return array
* Returns an array of structure types for use in form select options.
*/
function farm_structure_type_options() {
/** @var \Drupal\farm_structure\Entity\FarmStructureTypeInterface[] $types */
$types = \Drupal::entityTypeManager()->getStorage('structure_type')->loadMultiple();
$options = [];
foreach ($types as $id => $type) {
$options[$id] = $type->getLabel();
}
return $options;
}
/**
* Allowed values callback function for the structure type field.
*
@ -22,11 +38,5 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface;
* Returns an array of allowed values for use in form select options.
*/
function farm_structure_type_field_allowed_values(FieldStorageDefinitionInterface $definition, ContentEntityInterface $entity = NULL, bool &$cacheable = TRUE) {
/** @var \Drupal\farm_structure\Entity\FarmStructureTypeInterface[] $types */
$types = \Drupal::entityTypeManager()->getStorage('structure_type')->loadMultiple();
$allowed_values = [];
foreach ($types as $id => $type) {
$allowed_values[$id] = $type->getLabel();
}
return $allowed_values;
return farm_structure_type_options();
}

View File

@ -8,7 +8,6 @@
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\farm_flag\Entity\FarmFlagInterface;
use Drupal\farm_flag\Form\EntityFlagActionForm;
use Drupal\farm_flag\Routing\EntityFlagActionRouteProvider;
@ -37,6 +36,70 @@ function farm_flag_entity_base_field_info(EntityTypeInterface $entity_type) {
return $fields;
}
/**
* Flag options helper.
*
* @param string|null $entity_type
* The entity type. Returns all flags if NULL.
* @param string[] $bundles
* Array of bundle ids to limit to. An empty array loads all bundles.
* @param bool $intersection
* A flag indicating to return an intersection of the allowed options.
*
* @return array
* Returns an array of flags for use in form select options.
*/
function farm_flag_options(string $entity_type = NULL, array $bundles = [], bool $intersection = FALSE) {
/** @var \Drupal\farm_flag\Entity\FarmFlagInterface[] $flags */
$flags = \Drupal::entityTypeManager()->getStorage('flag')->loadMultiple();
// If an entity type is provided, begin the filtering process...
if (!empty($entity_type)) {
// If no bundles are specified, load all bundles of the entity type.
if (empty($bundles) && $bundle_entity_type = \Drupal::entityTypeManager()->getDefinition($entity_type)->getBundleEntityType()) {
$bundles = array_keys(\Drupal::entityTypeManager()
->getStorage($bundle_entity_type)
->loadMultiple());
}
// Find only the flags that apply to the entity type and bundles.
$flags = array_filter($flags, function ($flag) use ($entity_type, $bundles, $intersection) {
$flag_entity_types = $flag->getEntityTypes();
// The flag applies if no entity type is specified.
if (empty($flag_entity_types)) {
return TRUE;
}
// Otherwise the flag must specify the entity type.
if (!array_key_exists($entity_type, $flag_entity_types)) {
return FALSE;
}
// The flag applies to the bundle if:
// Case 1: The flag specifies 'all' bundles of the entity type.
$bundle_applies = in_array('all', $flag_entity_types[$entity_type]);
// Case 2: No intersection.
// The flag applies if any of the requested bundles are supported.
$bundle_applies |= !$intersection && !empty(array_intersect($bundles, $flag_entity_types[$entity_type]));
// Case 3: Intersection.
// The flag only applies if all the requested bundles are supported.
$bundle_applies |= $intersection && empty(array_diff($bundles, $flag_entity_types[$entity_type]));
return $bundle_applies;
});
}
// Assemble the options.
foreach ($flags as $id => $flag) {
$options[$id] = $flag->label();
}
return $options;
}
/**
* Allowed values callback function for the flags field.
*
@ -51,62 +114,14 @@ function farm_flag_entity_base_field_info(EntityTypeInterface $entity_type) {
* Returns an array of allowed values for use in form select options.
*/
function farm_flag_field_allowed_values(FieldStorageDefinitionInterface $definition, ContentEntityInterface $entity = NULL, bool &$cacheable = TRUE) {
/** @var \Drupal\farm_flag\Entity\FarmFlagInterface[] $flags */
$flags = \Drupal::entityTypeManager()->getStorage('flag')->loadMultiple();
$allowed_values = [];
$entity_type = NULL;
$bundle = NULL;
$bundles = [];
if (!empty($entity)) {
$cacheable = FALSE;
$entity_type = $entity->getEntityTypeId();
$bundle = $entity->bundle();
$bundles = [$entity->bundle()];
}
foreach ($flags as $id => $flag) {
if (farm_flag_applies($flag, $entity_type, $bundle)) {
$allowed_values[$id] = $flag->getLabel();
}
}
return $allowed_values;
}
/**
* Check to see if a flag applies to an entity type + bundle.
*
* @param \Drupal\farm_flag\Entity\FarmFlagInterface $flag
* The flag object.
* @param string|null $entity_type
* The entity type machine name.
* @param string|null $bundle
* The bundle name.
*
* @return bool
* Returns TRUE if the flag applies, FALSE otherwise.
*/
function farm_flag_applies(FarmFlagInterface $flag, $entity_type = NULL, $bundle = NULL) {
// If no entity type is specified, we assume the flag applies. This ensures
// it shows in lists/filters where the entity type may not be known.
if (empty($entity_type)) {
return TRUE;
}
// Load applicable entity types.
$entity_types = $flag->getEntityTypes();
// The flag applies if there are no allowed entity types specified.
if (empty($entity_types)) {
return TRUE;
}
// The flag applies if the entity type is in the list of applicable entity
// types, and the bundle is in the list of applicable bundles (or the flag
// applies to "all" bundles).
if (array_key_exists($entity_type, $entity_types) && (in_array($bundle, $entity_types[$entity_type]) || in_array('all', $entity_types[$entity_type]))) {
return TRUE;
}
// Otherwise, assume the flag does not apply.
return FALSE;
return farm_flag_options($entity_type, $bundles);
}
/**

View File

@ -161,19 +161,10 @@ class EntityFlagActionForm extends ConfirmFormBase {
// Get allowed values for the selected entities.
// We find the intersection of all the allowed values to ensure that
// disallowed flags cannot be assigned.
$allowed_values = [];
$field_storage_definitions = $this->entityFieldManager->getFieldStorageDefinitions($entity_type_id);
if (!empty($field_storage_definitions['flag'])) {
foreach ($this->entities as $entity) {
$entity_allowed_values = farm_flag_field_allowed_values($field_storage_definitions['flag'], $entity);
if (empty($allowed_values)) {
$allowed_values = $entity_allowed_values;
}
else {
$allowed_values = array_intersect_assoc($allowed_values, $entity_allowed_values);
}
}
}
$entity_bundles = array_unique(array_map(function ($entity) {
return $entity->bundle();
}, $this->entities));
$allowed_values = farm_flag_options($entity_type_id, $entity_bundles, TRUE);
$form['flags'] = [
'#type' => 'select',

View File

@ -0,0 +1,125 @@
<?php
namespace Drupal\Tests\farm_flag\Kernel;
use Drupal\farm_flag\Entity\FarmFlag;
use Drupal\Tests\token\Kernel\KernelTestBase;
/**
* Tests for farm_flag logic.
*
* @group farm_flag
*/
class FlagTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'farm_field',
'farm_flag',
'log',
'asset',
'state_machine',
];
/**
* Test farm flag options logic.
*/
public function testFarmFlagOptions() {
// Create a general flag that applies to all entity types.
$general_flag = FarmFlag::create([
'id' => 'general',
'label' => 'General',
'entity_types' => NULL,
]);
$general_flag->save();
// Create bundles and flags for testing.
$test_entity_types = [
'log' => ['activity', 'input', 'observation'],
'asset' => [],
];
foreach ($test_entity_types as $entity_type => $bundles) {
$entity_type_id = $entity_type . '_type';
// Create a flag for all bundles of the entity type.
$flag = FarmFlag::create([
'id' => $entity_type . '_flag',
'entity_types' => [
$entity_type => ['all'],
],
]);
$flag->save();
// Create bundles and a flag for each bundle.
foreach ($bundles as $bundle_id) {
// Create the bundle.
$bundle = \Drupal::entityTypeManager()->getStorage($entity_type_id)->create([
'id' => $bundle_id,
'workflow' => $entity_type . '_default',
]);
$bundle->save();
// Create a flag that only applies for the bundle.
$flag = FarmFlag::create([
'id' => $bundle_id . '_flag',
'entity_types' => [
$entity_type => [$bundle_id],
],
]);
$flag->save();
}
}
// Create a special flag that only applies to activity logs.
$flag = FarmFlag::create([
'id' => 'special_flag',
'entity_types' => [
'log' => ['activity'],
],
]);
$flag->save();
// Load all flag options.
$all_flags = \Drupal::entityTypeManager()->getStorage('flag')->loadMultiple();
$all_flag_ids = array_keys($all_flags);
// 1. With default parameters all flag options are returned.
$expected_flag_ids = array_keys(farm_flag_options());
$this->assertEmpty(array_diff($expected_flag_ids, $all_flag_ids), 'All flag options are returned.');
// 2. Flags applying to any asset type are returned.
$flag_ids = array_keys(farm_flag_options('asset'));
$expected_flag_ids = ['general', 'asset_flag'];
$this->assertEmpty(array_diff($expected_flag_ids, $flag_ids));
// 3. Flags applying to any log type are returned.
$flag_ids = array_keys(farm_flag_options('log'));
$expected_flag_ids = ['general', 'log_flag', 'special_flag', 'activity_flag', 'input_flag', 'observation_flag'];
$this->assertEmpty(array_diff($expected_flag_ids, $flag_ids));
// 4. Flags applying to every log type are returned.
$flag_ids = array_keys(farm_flag_options('log', [], TRUE));
$expected_flag_ids = ['general', 'log_flag'];
$this->assertEmpty(array_diff($expected_flag_ids, $flag_ids));
// 5. Flags applying to either activity or input log types are returned.
$flag_ids = array_keys(farm_flag_options('log', ['activity', 'input']));
$expected_flag_ids = ['general', 'log_flag', 'special_flag', 'activity_flag', 'input_flag'];
$this->assertEmpty(array_diff($expected_flag_ids, $flag_ids));
// 6. Flags applying to both activity and input log types are returned.
$flag_ids = array_keys(farm_flag_options('log', ['activity', 'input'], TRUE));
$expected_flag_ids = ['general', 'log_flag'];
$this->assertEmpty(array_diff($expected_flag_ids, $flag_ids));
// 7. Flags applying to only the activity log types are returned.
$flag_ids = array_keys(farm_flag_options('log', ['activity'], TRUE));
$expected_flag_ids = ['general', 'log_flag', 'special_flag', 'activity_flag'];
$this->assertEmpty(array_diff($expected_flag_ids, $flag_ids));
}
}

View File

@ -55,11 +55,17 @@ class ContentEntityGeometryNormalizer implements NormalizerInterface, Serializer
$geofield = $context['geofield'];
$entities = is_array($object) ? $object : [$object];
foreach ($entities as $entity) {
// If the entity doesn't have the configured geofield field, bail.
if (!$entity->hasField($geofield)) {
continue;
}
// If the geofield is empty, bail.
if ($entity->get($geofield)->isEmpty()) {
continue;
}
$field_value = $entity->get($geofield)->first();
$wkt = $field_value->get('value')->getValue();
if (!empty($wkt)) {

View File

@ -32,7 +32,7 @@ function farm_id_tag_entity_base_field_info(EntityTypeInterface $entity_type) {
}
/**
* Allowed values callback function for the ID tag type field.
* ID tag type options helper.
*
* @param string $bundle
* The asset bundle to get allowed values for.
@ -40,17 +40,17 @@ function farm_id_tag_entity_base_field_info(EntityTypeInterface $entity_type) {
* @return array
* Returns an array of allowed values for use in form select options.
*/
function farm_id_tag_type_allowed_values($bundle) {
function farm_id_tag_type_options(string $bundle) {
/** @var \Drupal\farm_id_tag\Entity\FarmIDTagTypeInterface[] $types */
$types = \Drupal::entityTypeManager()->getStorage('tag_type')->loadMultiple();
$allowed_values = [];
$options = [];
foreach ($types as $id => $type) {
$bundles = $type->getBundles();
if (empty($bundles) || in_array($bundle, $bundles)) {
$allowed_values[$id] = $type->getLabel();
$options[$id] = $type->getLabel();
}
}
return $allowed_values;
return $options;
}
/**

View File

@ -39,7 +39,7 @@ class IdTagWidget extends WidgetBase {
$bundle = $form_state->getStorage()['form_display']->get('bundle');
// Load allowed tag types.
$tag_types = farm_id_tag_type_allowed_values($bundle);
$tag_types = farm_id_tag_type_options($bundle);
$element['type'] = [
'#type' => 'select',

View File

@ -3,7 +3,6 @@
namespace Drupal\farm_import_kml\Form;
use Drupal\asset\Entity\Asset;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormBase;
@ -28,13 +27,6 @@ class KmlImporter extends FormBase {
*/
protected $entityTypeManager;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* The serializer service.
*
@ -54,16 +46,13 @@ class KmlImporter extends FormBase {
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager service.
* @param \Symfony\Component\Serializer\SerializerInterface $serializer
* The serializer service.
* @param \Drupal\Core\File\FileSystemInterface $file_system
* The file system service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, SerializerInterface $serializer, FileSystemInterface $file_system) {
public function __construct(EntityTypeManagerInterface $entity_type_manager, SerializerInterface $serializer, FileSystemInterface $file_system) {
$this->entityTypeManager = $entity_type_manager;
$this->entityFieldManager = $entity_field_manager;
$this->serializer = $serializer;
$this->fileSystem = $file_system;
}
@ -74,7 +63,6 @@ class KmlImporter extends FormBase {
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('entity_field.manager'),
$container->get('serializer'),
$container->get('file_system')
);
@ -110,11 +98,7 @@ class KmlImporter extends FormBase {
];
// Build land type options.
$land_type_options = [];
$field_storage_definitions = $this->entityFieldManager->getFieldStorageDefinitions('asset');
if (!empty($field_storage_definitions['land_type'])) {
$land_type_options = farm_land_type_field_allowed_values($field_storage_definitions['land_type']);
}
$land_type_options = farm_land_type_options();
$form['input']['land_type'] = [
'#type' => 'select',
'#title' => $this->t('Default land type'),

View File

@ -119,6 +119,11 @@ class KmlNormalizer implements NormalizerInterface, DenormalizerInterface {
// Load KML into a Geometry object.
$geometry = $this->geoPHP->load($placemark['xml'], 'kml');
// Create an empty collection if no geometry was loaded.
if (empty($geometry)) {
$geometry = new \GeometryCollection();
}
// Build properties.
$properties = [];

View File

@ -37,12 +37,16 @@
feature.set('name', names.length + ' item(s):');
}
// A popup name is required.
var name = featureName(feature) || '';
var description = feature.get('description') || '';
var measurement = instance.measureGeometry(feature.getGeometry(), instance.units);
if (name !== '') {
// A popup name is required, along with a measurement and/or description.
if (name !== '' && (measurement !== '' || description !== '')) {
// Get the description and measurement.
var description = feature.get('description') || '';
var measurement = instance.measureGeometry(feature.getGeometry(), instance.units);
// Build content with all three values, even if empty. The measurement and description divs may be used
// as placeholders for map behaviors to place additional information.
content = '<h4 class="ol-popup-name">' + name + '</h4><div class="ol-popup-measurement"><small>' + measurement + '</small></div><div class="ol-popup-description">' + description + '</div>';
}
}

View File

@ -68,7 +68,7 @@ class FarmMigrateCommands extends MigrateToolsCommands {
$options = [
'group' => $group,
];
$this->logger()->notice('Importing migration group: @group', ['@group' => $group]);
$this->logger()->notice('Importing migration group: ' . $group);
$this->import('', $options);
}
}
@ -86,7 +86,7 @@ class FarmMigrateCommands extends MigrateToolsCommands {
$options = [
'group' => $group,
];
$this->logger()->notice('Rolling back migration group: @group', ['@group' => $group]);
$this->logger()->notice('Rolling back migration group: ' . $group);
$this->rollback('', $options);
}
}

View File

@ -69,7 +69,7 @@ function quantity_measures() {
* Quantity measure options helper.
*
* @return array
* Returns an array of allowed values for use in form select options.
* Returns an array of quantity measures for use in form select options.
*/
function quantity_measure_options() {

View File

@ -3,6 +3,7 @@
namespace Drupal\farm_quick\Traits;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
/**
* Provides methods for loading prepopulated entity references.
@ -24,18 +25,38 @@ trait QuickPrepopulateTrait {
*
* @param string $entity_type
* The entity type to prepopulate.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return \Drupal\Core\Entity\EntityInterface[]
* An array of entities.
*/
protected function getPrepopulatedEntities(string $entity_type) {
protected function getPrepopulatedEntities(string $entity_type, FormStateInterface $form_state) {
// Initialize a temporary value in the form state.
if (!$form_state->hasTemporaryValue("quick_prepopulate_$entity_type")) {
$this->initPrepoluatedEntities($entity_type, $form_state);
}
// Return the prepopulated entities saved in the form state.
$entity_ids = $form_state->getTemporaryValue("quick_prepopulate_$entity_type") ?? [];
return \Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple($entity_ids);
}
/**
* Helper function to initialize prepopulated entities in the form state.
*
* @param string $entity_type
* The entity type to prepopulate.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*/
protected function initPrepoluatedEntities(string $entity_type, FormStateInterface $form_state) {
// Save the current user.
$user = \Drupal::currentUser();
// Load the temp store for the quick form.
// @todo Clear the temp store after form submission.
// Can we do this without another helper method on this trait?
/** @var \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory */
$temp_store_factory = \Drupal::service('tempstore.private');
$temp_store = $temp_store_factory->get('farm_quick.' . $this->getId());
@ -58,17 +79,27 @@ trait QuickPrepopulateTrait {
$query_entity_ids = [$query_entity_ids];
}
// Bail if there are no prepopulated entities.
// Only include the unique ids.
$entity_ids = array_unique(array_merge($temp_store_entity_ids, $query_entity_ids));
if (empty($entity_ids)) {
return [];
// Filter to entities the user has access to.
$accessible_entities = [];
if (!empty($entity_ids)) {
// Return entities the user has access to.
$entities = \Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple($entity_ids);
$accessible_entities = array_filter($entities, function (EntityInterface $asset) use ($user) {
return $asset->access('view', $user);
});
}
// Return entities the user has access to.
$entities = \Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple($entity_ids);
return array_filter($entities, function (EntityInterface $asset) use ($user) {
return $asset->access('view', $user);
});
// Save the accessible entity ids as a temporary value in the form state.
$accessible_entity_ids = array_map(function (EntityInterface $entity) {
return $entity->id();
}, $accessible_entities);
$form_state->setTemporaryValue("quick_prepopulate_$entity_type", $accessible_entity_ids);
// Finally, remove the entities from the temp store.
$temp_store->delete($temp_store_key);
}
}

View File

@ -115,24 +115,8 @@ function farm_ui_views_form_views_exposed_form_alter(&$form, FormStateInterface
// Get the entity type and (maybe) bundle.
$entity_type = $storage['view']->getBaseEntityType()->id();
$bundle = farm_ui_views_get_bundle_argument($storage['view'], $storage['display']['id'], $storage['view']->args);
// Load flag entities and filter out ones that don't apply.
/** @var \Drupal\farm_flag\Entity\FarmFlagInterface[] $flags */
$flags = \Drupal::entityTypeManager()->getStorage('flag')->loadMultiple();
$allowed_flag_ids = [];
foreach ($flags as $flag) {
if (farm_flag_applies($flag, $entity_type, $bundle)) {
$allowed_flag_ids[] = $flag->id();
}
}
// Alter exposed filters to remove flags that are not applicable.
$allowed_options = [];
foreach ($form['flag_value']['#options'] as $key => $value) {
if (in_array($key, $allowed_flag_ids)) {
$allowed_options[$key] = $value;
}
}
$bundles = !empty($bundle) ? [$bundle] : [];
$allowed_options = farm_flag_options($entity_type, $bundles, TRUE);
$form['flag_value']['#options'] = $allowed_options;
}

View File

@ -219,6 +219,16 @@ function farm_ui_views_add_bundle_handlers(ViewExecutable $view, string $display
$field_options['type'] = 'timestamp';
$field_options['settings']['date_format'] = 'html_date';
break;
case 'boolean':
case 'list_string':
case 'string':
// Field types that do not need any modifications.
break;
default:
// Do not add field handlers for unsupported field types.
continue 2;
}
// Add the field handler.
@ -311,6 +321,15 @@ function farm_ui_views_add_bundle_handlers(ViewExecutable $view, string $display
// String fields use the contains operator.
$filter_options['operator'] = 'contains';
break;
case 'list_string':
case 'timestamp':
// Field types that do not need any modifications.
break;
default:
// Do not add filter handlers for unsupported field types.
continue 2;
}
// Add the filter handler.

View File

@ -8,6 +8,22 @@
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
/**
* Lab test type options helper.
*
* @return array
* Returns an array of lab test types for use in form select options.
*/
function farm_lab_test_type_options() {
/** @var \Drupal\farm_lab_test\Entity\FarmLabTestTypeInterface[] $lab_test_types */
$lab_test_types = \Drupal::entityTypeManager()->getStorage('lab_test_type')->loadMultiple();
$options = [];
foreach ($lab_test_types as $id => $lab_test_type) {
$options[$id] = $lab_test_type->getLabel();
}
return $options;
}
/**
* Allowed values callback function for the lab test type field.
*
@ -22,11 +38,5 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface;
* Returns an array of allowed values for use in form select options.
*/
function farm_lab_test_type_field_allowed_values(FieldStorageDefinitionInterface $definition, ContentEntityInterface $entity = NULL, bool &$cacheable = TRUE) {
/** @var \Drupal\farm_lab_test\Entity\FarmLabTestTypeInterface[] $lab_test_types */
$lab_test_types = \Drupal::entityTypeManager()->getStorage('lab_test_type')->loadMultiple();
$allowed_values = [];
foreach ($lab_test_types as $id => $lab_test_type) {
$allowed_values[$id] = $lab_test_type->getLabel();
}
return $allowed_values;
return farm_lab_test_type_options();
}

View File

@ -21,5 +21,5 @@ settings:
min: null
max: null
prefix: ''
suffix: ' day|days'
suffix: ' day| days'
field_type: integer

View File

@ -21,5 +21,5 @@ settings:
min: null
max: null
prefix: ''
suffix: ' day|days'
suffix: ' day| days'
field_type: integer