Merge branch 'farmOS:2.x' into AssetOwners
This commit is contained in:
commit
218ad1c476
20
CHANGELOG.md
20
CHANGELOG.md
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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 = [];
|
||||
|
||||
|
|
|
@ -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>';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -21,5 +21,5 @@ settings:
|
|||
min: null
|
||||
max: null
|
||||
prefix: ''
|
||||
suffix: ' day|days'
|
||||
suffix: ' day| days'
|
||||
field_type: integer
|
||||
|
|
|
@ -21,5 +21,5 @@ settings:
|
|||
min: null
|
||||
max: null
|
||||
prefix: ''
|
||||
suffix: ' day|days'
|
||||
suffix: ' day| days'
|
||||
field_type: integer
|
||||
|
|
Loading…
Reference in New Issue