Move all Views hooks to *.views.inc and *.views_execution.inc include files.

This commit is contained in:
Michael Stenta 2021-06-04 08:03:55 -04:00
parent e783ff7604
commit 187bd7abcb
19 changed files with 714 additions and 657 deletions

View File

@ -7,7 +7,6 @@
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\ViewExecutable;
/**
* Implements hook_entity_base_field_info().
@ -29,95 +28,6 @@ function farm_group_entity_base_field_info(EntityTypeInterface $entity_type) {
}
}
/**
* Implements hook_views_data_alter().
*/
function farm_group_views_data_alter(array &$data) {
// Add the computed group membership field to assets.
$data['asset']['group'] = [
'title' => t('Current group'),
'field' => [
'id' => 'asset_group',
'field_name' => 'group',
],
'argument' => [
'id' => 'asset_group',
],
];
}
/**
* Implements hook_views_pre_view().
*/
function farm_group_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
// Alter the farm_asset View.
if ($view->id() == 'farm_asset') {
// Add the computed "Group" field before the "Location" field.
$field_options = [
'type' => 'entity_reference_label',
'label' => t('Group'),
'settings' => [
'link' => TRUE,
],
];
$field_id = $view->addHandler($display_id, 'field', 'asset', 'group', $field_options);
farm_ui_views_sort_field($view, $display_id, $field_id, 'location', TRUE);
}
// Alter the farm_log View.
if ($view->id() == 'farm_log') {
// Do not alter the upcoming/late block displays.
if (in_array($display_id, ['block_upcoming', 'block_late'])) {
return;
}
// Make sure the is_group_assignment field exists.
/** @var \Drupal\Core\Field\BaseFieldDefinition[] $definitions */
$definitions = \Drupal::service('entity_field.manager')
->getBaseFieldDefinitions('log');
if (isset($definitions['is_group_assignment'])) {
// Get field name and table name.
$definition = $definitions['is_group_assignment'];
$field_name = $definition->getName();
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = \Drupal::entityTypeManager()
->getStorage('log')
->getTableMapping();
$table = $table_mapping->getFieldTableName($definition->getName());
// Define filter options.
$opts = [
'operator' => '=',
'value' => 'All',
'exposed' => TRUE,
'expose' => [
'label' => t('Is group assignment'),
'identifier' => 'is_group_assignment',
],
];
// Add the filter.
$filter_id = $view->addHandler($view->current_display, 'filter', $table, $field_name, $opts);
// Move the is_group_assignment filter to render before the status filter.
$filters = $view->getDisplay()->getOption('filters');
if ($index = array_search('status', array_keys($filters))) {
$filter = $filters[$filter_id];
unset($filters[$filter_id]);
// Use array_merge + array_splice instead of array_splice so we can
// preserve the array keys.
$filters = array_merge(array_slice($filters, 0, $index), [$filter_id => $filter], array_slice($filters, $index));
}
// Set the new sorted filters array.
$view->getDisplay()->setOption('filters', $filters);
}
}
}
/**
* Implements hook_form_BASE_FORM_ID_alter().
*/

View File

@ -0,0 +1,24 @@
<?php
/**
* @file
* Provides Views data for farm_group.module.
*/
/**
* Implements hook_views_data_alter().
*/
function farm_group_views_data_alter(array &$data) {
// Add the computed group membership field to assets.
$data['asset']['group'] = [
'title' => t('Current group'),
'field' => [
'id' => 'asset_group',
'field_name' => 'group',
],
'argument' => [
'id' => 'asset_group',
],
];
}

View File

@ -0,0 +1,79 @@
<?php
/**
* @file
* Provides Views runtime hooks for farm_group.module.
*/
use Drupal\views\ViewExecutable;
/**
* Implements hook_views_pre_view().
*/
function farm_group_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
// Alter the farm_asset View.
if ($view->id() == 'farm_asset') {
// Add the computed "Group" field before the "Location" field.
$field_options = [
'type' => 'entity_reference_label',
'label' => t('Group'),
'settings' => [
'link' => TRUE,
],
];
$field_id = $view->addHandler($display_id, 'field', 'asset', 'group', $field_options);
farm_ui_views_sort_field($view, $display_id, $field_id, 'location', TRUE);
}
// Alter the farm_log View.
if ($view->id() == 'farm_log') {
// Do not alter the upcoming/late block displays.
if (in_array($display_id, ['block_upcoming', 'block_late'])) {
return;
}
// Make sure the is_group_assignment field exists.
/** @var \Drupal\Core\Field\BaseFieldDefinition[] $definitions */
$definitions = \Drupal::service('entity_field.manager')
->getBaseFieldDefinitions('log');
if (isset($definitions['is_group_assignment'])) {
// Get field name and table name.
$definition = $definitions['is_group_assignment'];
$field_name = $definition->getName();
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = \Drupal::entityTypeManager()
->getStorage('log')
->getTableMapping();
$table = $table_mapping->getFieldTableName($definition->getName());
// Define filter options.
$opts = [
'operator' => '=',
'value' => 'All',
'exposed' => TRUE,
'expose' => [
'label' => t('Is group assignment'),
'identifier' => 'is_group_assignment',
],
];
// Add the filter.
$filter_id = $view->addHandler($view->current_display, 'filter', $table, $field_name, $opts);
// Move the is_group_assignment filter to render before the status filter.
$filters = $view->getDisplay()->getOption('filters');
if ($index = array_search('status', array_keys($filters))) {
$filter = $filters[$filter_id];
unset($filters[$filter_id]);
// Use array_merge + array_splice instead of array_splice so we can
// preserve the array keys.
$filters = array_merge(array_slice($filters, 0, $index), [$filter_id => $filter], array_slice($filters, $index));
}
// Set the new sorted filters array.
$view->getDisplay()->setOption('filters', $filters);
}
}
}

View File

@ -5,9 +5,6 @@
* Land asset module.
*/
use Drupal\farm_land\Entity\FarmLandType;
use Drupal\views\ViewExecutable;
/**
* Allowed values callback function for the land type field.
*
@ -23,57 +20,3 @@ function farm_land_type_field_allowed_values() {
}
return $allowed_values;
}
/**
* Implements hook_views_pre_render().
*/
function farm_land_views_pre_render(ViewExecutable $view) {
// Add land type map layers to the land assets map.
if ($view->id() == 'farm_asset' && $view->current_display == 'page_type' && !empty($view->args[0]) && $view->args[0] == 'land') {
// If the asset_map has not been added, bail.
if (empty($view->attachment_before['asset_map'])) {
return;
}
$map = &$view->attachment_before['asset_map'];
// Load all land types.
$land_types = FarmLandType::loadMultiple();
// Get exposed filters.
$exposed_filters = $view->getExposedInput();
// If the land type exposed filter is already in use remove land types
// that are not included.
if (!empty($exposed_filters['land_type_value'])) {
$land_types = array_filter($land_types, function ($key) use ($exposed_filters) {
return in_array($key, $exposed_filters['land_type_value']);
}, ARRAY_FILTER_USE_KEY);
}
// Create a layer for each land type.
$asset_layers = [];
foreach ($land_types as $land_type) {
/** @var \Drupal\farm_map\Entity\LayerStyleInterface $layer_style */
$layer_style = \Drupal::service('farm_map.layer_style_loader')->load(['asset_type' => 'land', 'land_type' => $land_type->id()]);
if (!empty($layer_style)) {
$color = $layer_style->get('color');
}
$asset_layers['land_' . $land_type->id()] = [
'group' => t('Land types'),
'label' => $land_type->label(),
'asset_type' => 'land',
'filters' => $exposed_filters + ['land_type_value[]' => $land_type->id()],
'color' => $color ?? 'orange',
'zoom' => TRUE,
];
}
// Add layers to the map settings.
$map['#map_settings']['asset_type_layers'] = array_merge($map['#map_settings']['asset_type_layers'], $asset_layers);
// Remove the land asset layer.
unset($map['#map_settings']['asset_type_layers']['full_land']);
}
}

View File

@ -0,0 +1,63 @@
<?php
/**
* @file
* Provides Views runtime hooks for farm_land.module.
*/
use Drupal\farm_land\Entity\FarmLandType;
use Drupal\views\ViewExecutable;
/**
* Implements hook_views_pre_render().
*/
function farm_land_views_pre_render(ViewExecutable $view) {
// Add land type map layers to the land assets map.
if ($view->id() == 'farm_asset' && $view->current_display == 'page_type' && !empty($view->args[0]) && $view->args[0] == 'land') {
// If the asset_map has not been added, bail.
if (empty($view->attachment_before['asset_map'])) {
return;
}
$map = &$view->attachment_before['asset_map'];
// Load all land types.
$land_types = FarmLandType::loadMultiple();
// Get exposed filters.
$exposed_filters = $view->getExposedInput();
// If the land type exposed filter is already in use remove land types
// that are not included.
if (!empty($exposed_filters['land_type_value'])) {
$land_types = array_filter($land_types, function ($key) use ($exposed_filters) {
return in_array($key, $exposed_filters['land_type_value']);
}, ARRAY_FILTER_USE_KEY);
}
// Create a layer for each land type.
$asset_layers = [];
foreach ($land_types as $land_type) {
/** @var \Drupal\farm_map\Entity\LayerStyleInterface $layer_style */
$layer_style = \Drupal::service('farm_map.layer_style_loader')->load(['asset_type' => 'land', 'land_type' => $land_type->id()]);
if (!empty($layer_style)) {
$color = $layer_style->get('color');
}
$asset_layers['land_' . $land_type->id()] = [
'group' => t('Land types'),
'label' => $land_type->label(),
'asset_type' => 'land',
'filters' => $exposed_filters + ['land_type_value[]' => $land_type->id()],
'color' => $color ?? 'orange',
'zoom' => TRUE,
];
}
// Add layers to the map settings.
$map['#map_settings']['asset_type_layers'] = array_merge($map['#map_settings']['asset_type_layers'], $asset_layers);
// Remove the land asset layer.
unset($map['#map_settings']['asset_type_layers']['full_land']);
}
}

View File

@ -5,9 +5,6 @@
* Structure asset module.
*/
use Drupal\farm_structure\Entity\FarmStructureType;
use Drupal\views\ViewExecutable;
/**
* Allowed values callback function for the structure type field.
*
@ -23,57 +20,3 @@ function farm_structure_type_field_allowed_values() {
}
return $allowed_values;
}
/**
* Implements hook_views_pre_render().
*/
function farm_structure_views_pre_render(ViewExecutable $view) {
// Add structure type map layers to the structure assets map.
if ($view->id() == 'farm_asset' && $view->current_display == 'page_type' && !empty($view->args[0]) && $view->args[0] == 'structure') {
// If the asset_map has not been added, bail.
if (empty($view->attachment_before['asset_map'])) {
return;
}
$map = &$view->attachment_before['asset_map'];
// Load all structure types.
$structure_types = FarmStructureType::loadMultiple();
// Get exposed filters.
$exposed_filters = $view->getExposedInput();
// If the structure type exposed filter is already in use remove structure
// types that are not included.
if (!empty($exposed_filters['structure_type_value'])) {
$structure_types = array_filter($structure_types, function ($key) use ($exposed_filters) {
return in_array($key, $exposed_filters['structure_type_value']);
}, ARRAY_FILTER_USE_KEY);
}
// Create a layer for each structure type.
$asset_layers = [];
foreach ($structure_types as $structure_type) {
/** @var \Drupal\farm_map\Entity\LayerStyleInterface $layer_style */
$layer_style = \Drupal::service('farm_map.layer_style_loader')->load(['asset_type' => 'structure', 'structure_type' => $structure_type->id()]);
if (!empty($layer_style)) {
$color = $layer_style->get('color');
}
$asset_layers['structure_' . $structure_type->id()] = [
'group' => t('Structure types'),
'label' => $structure_type->label(),
'asset_type' => 'structure',
'filters' => $exposed_filters + ['structure_type_value[]' => $structure_type->id()],
'color' => $color ?? 'orange',
'zoom' => TRUE,
];
}
// Add layers to the map settings.
$map['#map_settings']['asset_type_layers'] = array_merge($map['#map_settings']['asset_type_layers'], $asset_layers);
// Remove the structure asset layer.
unset($map['#map_settings']['asset_type_layers']['full_structure']);
}
}

View File

@ -0,0 +1,63 @@
<?php
/**
* @file
* Provides Views runtime hooks for farm_structure.module.
*/
use Drupal\farm_structure\Entity\FarmStructureType;
use Drupal\views\ViewExecutable;
/**
* Implements hook_views_pre_render().
*/
function farm_structure_views_pre_render(ViewExecutable $view) {
// Add structure type map layers to the structure assets map.
if ($view->id() == 'farm_asset' && $view->current_display == 'page_type' && !empty($view->args[0]) && $view->args[0] == 'structure') {
// If the asset_map has not been added, bail.
if (empty($view->attachment_before['asset_map'])) {
return;
}
$map = &$view->attachment_before['asset_map'];
// Load all structure types.
$structure_types = FarmStructureType::loadMultiple();
// Get exposed filters.
$exposed_filters = $view->getExposedInput();
// If the structure type exposed filter is already in use remove structure
// types that are not included.
if (!empty($exposed_filters['structure_type_value'])) {
$structure_types = array_filter($structure_types, function ($key) use ($exposed_filters) {
return in_array($key, $exposed_filters['structure_type_value']);
}, ARRAY_FILTER_USE_KEY);
}
// Create a layer for each structure type.
$asset_layers = [];
foreach ($structure_types as $structure_type) {
/** @var \Drupal\farm_map\Entity\LayerStyleInterface $layer_style */
$layer_style = \Drupal::service('farm_map.layer_style_loader')->load(['asset_type' => 'structure', 'structure_type' => $structure_type->id()]);
if (!empty($layer_style)) {
$color = $layer_style->get('color');
}
$asset_layers['structure_' . $structure_type->id()] = [
'group' => t('Structure types'),
'label' => $structure_type->label(),
'asset_type' => 'structure',
'filters' => $exposed_filters + ['structure_type_value[]' => $structure_type->id()],
'color' => $color ?? 'orange',
'zoom' => TRUE,
];
}
// Add layers to the map settings.
$map['#map_settings']['asset_type_layers'] = array_merge($map['#map_settings']['asset_type_layers'], $asset_layers);
// Remove the structure asset layer.
unset($map['#map_settings']['asset_type_layers']['full_structure']);
}
}

View File

@ -2,13 +2,11 @@
/**
* @file
* Provide Views data for the basic data stream.
* Provide Views data for data_stream.module.
*/
/**
* Implements hook_views_data().
*
* Views integration for basic data stream data.
*/
function data_stream_views_data() {
$data = [];

View File

@ -281,32 +281,3 @@ function farm_entity_modules_installed($modules, $is_syncing) {
\Drupal::service('views.views_data')->clear();
}
}
/**
* Implements hook_views_data_alter().
*/
function farm_entity_views_data_alter(array &$data) {
// Because Drupal core does not provide full Views integration for base fields
// we must manually add support for certain fields.
// Workaround for core issue #2489476.
// Add support for state_machine filters.
$status_filter = [
'id' => 'state_machine_state',
'field_name' => 'status',
];
$tables = [
'asset_field_data',
'asset_field_revision',
'log_field_data',
'log_field_revision',
'plan_field_data',
'plan_field_revision',
];
foreach ($tables as $table) {
if (!empty($data[$table]['status'])) {
$data[$table]['status']['filter'] = $status_filter;
}
}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* @file
* Provides Views data for farm_entity.module.
*/
/**
* Implements hook_views_data_alter().
*/
function farm_entity_views_data_alter(array &$data) {
// Because Drupal core does not provide full Views integration for base fields
// we must manually add support for certain fields.
// Workaround for core issue #2489476.
// Add support for state_machine filters.
$status_filter = [
'id' => 'state_machine_state',
'field_name' => 'status',
];
$tables = [
'asset_field_data',
'asset_field_revision',
'log_field_data',
'log_field_revision',
'plan_field_data',
'plan_field_revision',
];
foreach ($tables as $table) {
if (!empty($data[$table]['status'])) {
$data[$table]['status']['filter'] = $status_filter;
}
}
}

View File

@ -5,34 +5,6 @@
* The farmOS Flags module.
*/
/**
* Implements hook_views_data_alter().
*/
function farm_flag_views_data_alter(array &$data) {
// Because Drupal core does not provide full Views integration for base fields
// we must manually specify the list_field views filter for the flag field.
// Define the views filter settings.
$flag_filter = [
'id' => 'list_field',
'field_name' => 'flag',
'allow_empty' => TRUE,
];
$tables = [
'asset__flag',
'asset_revision__flag',
'log__flag',
'log_revision__flag',
'plan__flag',
'plan_revision__flag',
];
foreach ($tables as $table) {
if (!empty($data[$table]['flag_value'])) {
$data[$table]['flag_value']['filter'] = $flag_filter;
}
}
}
/**
* Allowed values callback function for the flags field.
*

View File

@ -0,0 +1,34 @@
<?php
/**
* @file
* Provides Views data for farm_flag.module.
*/
/**
* Implements hook_views_data_alter().
*/
function farm_flag_views_data_alter(array &$data) {
// Because Drupal core does not provide full Views integration for base fields
// we must manually specify the list_field views filter for the flag field.
// Define the views filter settings.
$flag_filter = [
'id' => 'list_field',
'field_name' => 'flag',
'allow_empty' => TRUE,
];
$tables = [
'asset__flag',
'asset_revision__flag',
'log__flag',
'log_revision__flag',
'plan__flag',
'plan_revision__flag',
];
foreach ($tables as $table) {
if (!empty($data[$table]['flag_value'])) {
$data[$table]['flag_value']['filter'] = $flag_filter;
}
}
}

View File

@ -44,37 +44,6 @@ function farm_location_entity_base_field_info(EntityTypeInterface $entity_type)
}
}
/**
* Implements hook_views_data_alter().
*/
function farm_location_views_data_alter(array &$data) {
// Add computed fields to assets.
if (isset($data['asset'])) {
// Computed geometry.
$data['asset']['geometry'] = [
'title' => t('Geometry'),
'field' => [
'id' => 'asset_geometry',
'field_name' => 'geometry',
],
];
// Computed location.
$data['asset']['location'] = [
'title' => t('Current location'),
'field' => [
'id' => 'asset_location',
'field_name' => 'location',
],
'argument' => [
'id' => 'asset_location',
],
];
}
}
/**
* Sets the default value for asset is_location boolean field.
*

View File

@ -0,0 +1,37 @@
<?php
/**
* @file
* Provides Views data for farm_location.module.
*/
/**
* Implements hook_views_data_alter().
*/
function farm_location_views_data_alter(array &$data) {
// Add computed fields to assets.
if (isset($data['asset'])) {
// Computed geometry.
$data['asset']['geometry'] = [
'title' => t('Geometry'),
'field' => [
'id' => 'asset_geometry',
'field_name' => 'geometry',
],
];
// Computed location.
$data['asset']['location'] = [
'title' => t('Current location'),
'field' => [
'id' => 'asset_location',
'field_name' => 'location',
],
'argument' => [
'id' => 'asset_location',
],
];
}
}

View File

@ -2,7 +2,7 @@
/**
* @file
* Farm_quantity_price module views integration.
* Provides Views data for farm_quantity_price.module.
*/
/**

View File

@ -5,10 +5,6 @@
* The farmOS UI Map module.
*/
use Drupal\asset\Entity\AssetType;
use Drupal\views\Entity\View;
use Drupal\views\ViewExecutable;
/**
* Implements hook_farm_dashboard_panes().
*/
@ -20,138 +16,6 @@ function farm_ui_map_farm_dashboard_panes() {
];
}
/**
* Implements hook_views_pre_view().
*/
function farm_ui_map_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
// Alter the farm_asset_geojson View's full and centroid displays to add all
// exposed filters that are present in the farm_asset View.
if ($view->id() == 'farm_asset_geojson' && in_array($display_id, ['full', 'centroid'])) {
// Load the farm_asset View. Bail if unavailable.
$farm_asset_view = View::load('farm_asset');
if (empty($farm_asset_view)) {
return;
}
// Copy all exposed filters from the default display.
$display = $farm_asset_view->getDisplay('default');
if (!empty($display['display_options']['filters'])) {
foreach ($display['display_options']['filters'] as $field => $filter) {
$view->addHandler($display_id, 'filter', $filter['table'], $field, $filter, $filter['id']);
}
}
// If a type argument is present, add bundle-specific exposed filters.
if (!empty($args[0]) && $args[0] != 'all') {
farm_ui_views_add_bundle_handlers($view, $display_id, $args[0], 'filter');
}
}
}
/**
* Implements hook_views_pre_render().
*/
function farm_ui_map_views_pre_render(ViewExecutable $view) {
// Render a map attachment above views of assets.
if ($view->id() == 'farm_asset' && in_array($view->current_display, ['page', 'page_type'])) {
// Get all asset bundles.
$asset_bundles = \Drupal::service('entity_type.bundle.info')->getBundleInfo($view->getBaseEntityType()->id());
// Start array of filtered bundles.
$filtered_bundles = $asset_bundles;
// Start array of asset layers to add.
$asset_layers = [
'full' => [],
];
// Save the group labels.
$layer_group = $view->getBaseEntityType()->getCollectionLabel();
// Add multiple asset layers to the page of all assets.
if ($view->current_display == 'page') {
// Limit to filtered asset types.
if (!empty($exposed_filters['type'])) {
$filtered_bundles = array_intersect_key($asset_bundles, array_flip($exposed_filters['type']));
}
}
// Get exposed filters.
$exposed_filters = $view->getExposedInput();
// Determine if we are filtering by bundle.
// This may happen via contextual filter on the "page_type" display, or via
// the exposed "type" filter.
$bundle_filters = [];
if ($view->current_display == 'page_type' && !empty($view->args[0])) {
$bundle_filters[] = $view->args[0];
}
elseif (!empty($exposed_filters['type'])) {
foreach ($exposed_filters['type'] as $bundle) {
$bundle_filters[] = $bundle;
}
}
// Filter by bundle, if desired.
if (!empty($bundle_filters)) {
$filtered_bundles = [];
foreach ($bundle_filters as $bundle) {
$filtered_bundles[$bundle] = $asset_bundles[$bundle];
}
}
// Add a cluster layer for summarizing asset counts.
$asset_layers['cluster']['all'] = [
'label' => t('Asset counts'),
'cluster' => TRUE,
'filters' => $exposed_filters,
];
if (!empty($bundle_filters)) {
$asset_layers['cluster']['all']['asset_type'] = implode('+', $bundle_filters);
}
// Add a full asset geometry layer for each asset type.
foreach ($filtered_bundles as $bundle => $bundle_info) {
// Load the bundle entity.
$type = AssetType::load($bundle);
// Load the map layer style.
/** @var \Drupal\farm_map\Entity\LayerStyleInterface $layer_style */
$layer_style = \Drupal::service('farm_map.layer_style_loader')->load(['asset_type' => $bundle]);
if (!empty($layer_style)) {
$color = $layer_style->get('color');
}
// Add layer for the asset type.
$asset_layers['full']['full_' . $bundle] = [
'group' => $type->getThirdPartySetting('farm_location', 'is_location', FALSE) ? t('Location assets') : $layer_group,
'label' => $bundle_info['label'],
'asset_type' => $bundle,
'filters' => $exposed_filters,
'color' => $color ?? 'orange',
'zoom' => TRUE,
];
}
// Build the map render array.
$map = [
'#type' => 'farm_map',
'#map_type' => 'asset_list',
];
$all_layers = array_merge($asset_layers['cluster'], $asset_layers['full']);
$map['#map_settings']['asset_type_layers'] = $all_layers;
// Render the map.
$view->attachment_before['asset_map'] = $map;
}
}
/**
* Implements hook_module_implements_alter().
*/

View File

@ -0,0 +1,144 @@
<?php
/**
* @file
* Provides Views runtime hooks for farm_ui_map.module.
*/
use Drupal\asset\Entity\AssetType;
use Drupal\views\Entity\View;
use Drupal\views\ViewExecutable;
/**
* Implements hook_views_pre_view().
*/
function farm_ui_map_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
// Alter the farm_asset_geojson View's full and centroid displays to add all
// exposed filters that are present in the farm_asset View.
if ($view->id() == 'farm_asset_geojson' && in_array($display_id, ['full', 'centroid'])) {
// Load the farm_asset View. Bail if unavailable.
$farm_asset_view = View::load('farm_asset');
if (empty($farm_asset_view)) {
return;
}
// Copy all exposed filters from the default display.
$display = $farm_asset_view->getDisplay('default');
if (!empty($display['display_options']['filters'])) {
foreach ($display['display_options']['filters'] as $field => $filter) {
$view->addHandler($display_id, 'filter', $filter['table'], $field, $filter, $filter['id']);
}
}
// If a type argument is present, add bundle-specific exposed filters.
if (!empty($args[0]) && $args[0] != 'all') {
farm_ui_views_add_bundle_handlers($view, $display_id, $args[0], 'filter');
}
}
}
/**
* Implements hook_views_pre_render().
*
* @see farm_ui_map_module_implements_alter()
*/
function farm_ui_map_views_pre_render(ViewExecutable $view) {
// Render a map attachment above views of assets.
if ($view->id() == 'farm_asset' && in_array($view->current_display, ['page', 'page_type'])) {
// Get all asset bundles.
$asset_bundles = \Drupal::service('entity_type.bundle.info')->getBundleInfo($view->getBaseEntityType()->id());
// Start array of filtered bundles.
$filtered_bundles = $asset_bundles;
// Start array of asset layers to add.
$asset_layers = [
'full' => [],
];
// Save the group labels.
$layer_group = $view->getBaseEntityType()->getCollectionLabel();
// Add multiple asset layers to the page of all assets.
if ($view->current_display == 'page') {
// Limit to filtered asset types.
if (!empty($exposed_filters['type'])) {
$filtered_bundles = array_intersect_key($asset_bundles, array_flip($exposed_filters['type']));
}
}
// Get exposed filters.
$exposed_filters = $view->getExposedInput();
// Determine if we are filtering by bundle.
// This may happen via contextual filter on the "page_type" display, or via
// the exposed "type" filter.
$bundle_filters = [];
if ($view->current_display == 'page_type' && !empty($view->args[0])) {
$bundle_filters[] = $view->args[0];
}
elseif (!empty($exposed_filters['type'])) {
foreach ($exposed_filters['type'] as $bundle) {
$bundle_filters[] = $bundle;
}
}
// Filter by bundle, if desired.
if (!empty($bundle_filters)) {
$filtered_bundles = [];
foreach ($bundle_filters as $bundle) {
$filtered_bundles[$bundle] = $asset_bundles[$bundle];
}
}
// Add a cluster layer for summarizing asset counts.
$asset_layers['cluster']['all'] = [
'label' => t('Asset counts'),
'cluster' => TRUE,
'filters' => $exposed_filters,
];
if (!empty($bundle_filters)) {
$asset_layers['cluster']['all']['asset_type'] = implode('+', $bundle_filters);
}
// Add a full asset geometry layer for each asset type.
foreach ($filtered_bundles as $bundle => $bundle_info) {
// Load the bundle entity.
$type = AssetType::load($bundle);
// Load the map layer style.
/** @var \Drupal\farm_map\Entity\LayerStyleInterface $layer_style */
$layer_style = \Drupal::service('farm_map.layer_style_loader')->load(['asset_type' => $bundle]);
if (!empty($layer_style)) {
$color = $layer_style->get('color');
}
// Add layer for the asset type.
$asset_layers['full']['full_' . $bundle] = [
'group' => $type->getThirdPartySetting('farm_location', 'is_location', FALSE) ? t('Location assets') : $layer_group,
'label' => $bundle_info['label'],
'asset_type' => $bundle,
'filters' => $exposed_filters,
'color' => $color ?? 'orange',
'zoom' => TRUE,
];
}
// Build the map render array.
$map = [
'#type' => 'farm_map',
'#map_type' => 'asset_list',
];
$all_layers = array_merge($asset_layers['cluster'], $asset_layers['full']);
$map['#map_settings']['asset_type_layers'] = $all_layers;
// Render the map.
$view->attachment_before['asset_map'] = $map;
}
}

View File

@ -7,7 +7,6 @@
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\views\ViewExecutable;
use Drupal\views\Views;
/**
* Implements hook_entity_type_build().
@ -115,203 +114,6 @@ function farm_ui_views_entity_base_field_info_alter(&$fields, EntityTypeInterfac
}
}
/**
* Implements hook_views_pre_view().
*/
function farm_ui_views_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
// We only want to alter the Views we provide.
if (!in_array($view->id(), ['farm_asset', 'farm_log', 'farm_plan', 'farm_quantity'])) {
return;
}
// If this is a "By type" display, alter the fields and filters.
$bundle = FALSE;
if ($display_id == 'page_type' && !empty($args[0])) {
$bundle = $args[0];
}
elseif ($view->id() == 'farm_log' && $display_id == 'page_asset' && !empty($args[1]) && $args[1] != 'all') {
$bundle = $args[1];
}
if (!empty($bundle)) {
// Remove the type field and filter handlers.
$view->removeHandler($display_id, 'field', 'type');
$view->removeHandler($display_id, 'filter', 'type');
// If the entity type has a bundle_plugin manager, add all of its
// bundle fields and filters to the page_type view.
if (\Drupal::entityTypeManager()->hasHandler($view->getBaseEntityType()->id(), 'bundle_plugin')) {
farm_ui_views_add_bundle_handlers($view, $display_id, $bundle, 'field');
farm_ui_views_add_bundle_handlers($view, $display_id, $bundle, 'filter');
}
}
// If this is the "Upcoming" or "Late" Logs block display, add a "more" link
// that points to the default page display with appropriate filters.
if ($view->id() == 'farm_log' && in_array($display_id, ['block_upcoming', 'block_late'])) {
$view->display_handler->setOption('use_more', TRUE);
$view->display_handler->setOption('use_more_always', TRUE);
$view->display_handler->setOption('link_display', 'custom_url');
$today = date('Y-m-d', \Drupal::time()->getRequestTime());
if ($display_id == 'block_upcoming') {
$view->display_handler->setOption('use_more_text', t('View all upcoming logs'));
$view->display_handler->setOption('link_url', 'logs?status[]=pending&start=' . $today);
}
elseif ($display_id == 'block_late') {
$view->display_handler->setOption('use_more_text', t('View all late logs'));
$view->display_handler->setOption('link_url', 'logs?status[]=pending&end=' . $today);
}
}
}
/**
* Helper function for adding bundle-specific field and filter handlers.
*
* @param \Drupal\views\ViewExecutable $view
* The View to add handlers to.
* @param string $display_id
* The ID of the View display to add handlers to.
* @param string $bundle
* The bundle name.
* @param string $type
* The handler type ('field' or 'filter').
*/
function farm_ui_views_add_bundle_handlers(ViewExecutable $view, string $display_id, string $bundle, string $type) {
// Get the entity and bundle.
$base_entity = $view->getBaseEntityType();
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = \Drupal::entityTypeManager()->getStorage($base_entity->id())->getTableMapping();
// Load bundle fields.
/** @var \Drupal\entity\BundleFieldDefinition[] $bundle_fields */
$bundle_fields = \Drupal::entityTypeManager()->getHandler($base_entity->id(), 'bundle_plugin')->getFieldDefinitions($bundle);
foreach (array_reverse($bundle_fields) as $field_name => $field_definition) {
// Skip the bundle field if the view display was set as "hidden".
$view_options = $field_definition->getDisplayOptions('view');
if (empty($view_options) || (!empty($view_options['region']) && $view_options['region'] == 'hidden')) {
continue;
}
// Save the field type.
$field_type = $field_definition->getType();
// Get the field's table column (main property name).
$table = $table_mapping->getFieldTableName($field_name);
$property_name = $field_definition->getFieldStorageDefinition()->getMainPropertyName();
// Build the column and table names.
$column_name = $field_name . '_' . $property_name;
$views_option_name = $table . '.' . $column_name;
// Add a field handler if a views data field definition exists.
if ($type == 'field') {
$field_options = Views::viewsDataHelper()->fetchFields($table, 'field');
if (isset($field_options[$views_option_name])) {
// Build field options for the field type.
$field_options = [];
switch ($field_type) {
case 'entity_reference':
$target_type = $field_definition->getSetting('target_type');
// Do not render a link to referenced taxonomy terms.
if ($target_type === 'taxonomy_term') {
$field_options['type'] = 'entity_reference_label';
$field_options['settings']['link'] = FALSE;
}
break;
case 'timestamp':
// Render timestamp fields in the html_date format.
$field_options['type'] = 'timestamp';
$field_options['settings']['date_format'] = 'html_date';
break;
}
// Add the field handler.
$new_field_id = $view->addHandler($display_id, 'field', $table, $column_name, $field_options);
// Determine what position to insert the field handler.
switch ($base_entity->id()) {
case 'asset':
case 'plan':
$sort_field = 'name';
break;
case 'log':
$sort_field = 'quantity_target_id';
break;
case 'quantity':
default:
$sort_field = FALSE;
break;
}
// Sort the field handlers if necessary.
if (!empty($sort_field)) {
farm_ui_views_sort_field($view, $display_id, $new_field_id, $sort_field);
}
}
}
// Add a filter handler if a views data filter definition exists.
elseif ($type == 'filter') {
$filter_options = Views::viewsDataHelper()->fetchFields($table, 'filter');
if (isset($filter_options[$views_option_name])) {
$filter_options = [
'id' => $field_name,
'table' => $table,
'field' => $column_name,
'exposed' => TRUE,
'expose' => [
'operator_id' => $column_name . '_op',
'label' => $filter_options[$views_option_name]['title'],
'identifier' => $column_name,
'multiple' => TRUE,
],
'entity_type' => $base_entity->id(),
'entity_field' => $field_name,
];
// Build filter options for the field type.
switch ($field_type) {
case 'entity_reference':
$target_type = $field_definition->getSetting('target_type');
// Use a select widget for taxonomy term references.
if ($target_type === 'taxonomy_term') {
$filter_options['type'] = 'select';
// Limit to specific vocabularies if configured.
$handler_settings = $field_definition->getSetting('handler_settings');
$filter_options['limit'] = FALSE;
if (!empty($handler_settings['target_bundles'])) {
$filter_options['limit'] = TRUE;
$filter_options['vid'] = reset($handler_settings['target_bundles']);
}
}
break;
case 'string':
// String fields use the contains operator.
$filter_options['operator'] = 'contains';
break;
}
// Add the filter handler.
$view->addHandler($display_id, 'filter', $table, $column_name, $filter_options);
}
}
}
}
/**
* Helper function for sorting a field handler.
*
@ -352,30 +154,3 @@ function farm_ui_views_sort_field(ViewExecutable $view, string $display_id, stri
// Set the display to use the sorted field handlers.
$display->setOption($types[$type]['plural'], $new_field_handlers);
}
/**
* Implements hook_views_pre_render().
*/
function farm_ui_views_views_pre_render(ViewExecutable $view) {
// We only want to alter the Views we provide.
if (!in_array($view->id(), ['farm_asset', 'farm_log', 'farm_plan', 'farm_quantity'])) {
return;
}
// If this is a "By type" display and a bundle argument is specified, load
// the bundle label and set the title.
$bundle = FALSE;
if ($view->current_display == 'page_type' && !empty($view->args[0])) {
$bundle = $view->args[0];
}
elseif ($view->id() == 'farm_log' && $view->current_display == 'page_asset' && !empty($view->args[1]) && $view->args[1] != 'all') {
$bundle = $view->args[1];
}
if (!empty($bundle)) {
$bundles = \Drupal::service('entity_type.bundle.info')->getBundleInfo($view->getBaseEntityType()->id());
if (!empty($bundles[$bundle])) {
$view->setTitle($bundles[$bundle]['label'] . ' ' . $view->getBaseEntityType()->getPluralLabel());
}
}
}

View File

@ -0,0 +1,233 @@
<?php
/**
* @file
* Provides Views runtime hooks for farm_ui_views.module.
*/
use Drupal\views\ViewExecutable;
use Drupal\views\Views;
/**
* Implements hook_views_pre_view().
*/
function farm_ui_views_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
// We only want to alter the Views we provide.
if (!in_array($view->id(), ['farm_asset', 'farm_log', 'farm_plan', 'farm_quantity'])) {
return;
}
// If this is a "By type" display, alter the fields and filters.
$bundle = FALSE;
if ($display_id == 'page_type' && !empty($args[0])) {
$bundle = $args[0];
}
elseif ($view->id() == 'farm_log' && $display_id == 'page_asset' && !empty($args[1]) && $args[1] != 'all') {
$bundle = $args[1];
}
if (!empty($bundle)) {
// Remove the type field and filter handlers.
$view->removeHandler($display_id, 'field', 'type');
$view->removeHandler($display_id, 'filter', 'type');
// If the entity type has a bundle_plugin manager, add all of its
// bundle fields and filters to the page_type view.
if (\Drupal::entityTypeManager()->hasHandler($view->getBaseEntityType()->id(), 'bundle_plugin')) {
farm_ui_views_add_bundle_handlers($view, $display_id, $bundle, 'field');
farm_ui_views_add_bundle_handlers($view, $display_id, $bundle, 'filter');
}
}
// If this is the "Upcoming" or "Late" Logs block display, add a "more" link
// that points to the default page display with appropriate filters.
if ($view->id() == 'farm_log' && in_array($display_id, ['block_upcoming', 'block_late'])) {
$view->display_handler->setOption('use_more', TRUE);
$view->display_handler->setOption('use_more_always', TRUE);
$view->display_handler->setOption('link_display', 'custom_url');
$today = date('Y-m-d', \Drupal::time()->getRequestTime());
if ($display_id == 'block_upcoming') {
$view->display_handler->setOption('use_more_text', t('View all upcoming logs'));
$view->display_handler->setOption('link_url', 'logs?status[]=pending&start=' . $today);
}
elseif ($display_id == 'block_late') {
$view->display_handler->setOption('use_more_text', t('View all late logs'));
$view->display_handler->setOption('link_url', 'logs?status[]=pending&end=' . $today);
}
}
}
/**
* Implements hook_views_pre_render().
*/
function farm_ui_views_views_pre_render(ViewExecutable $view) {
// We only want to alter the Views we provide.
if (!in_array($view->id(), ['farm_asset', 'farm_log', 'farm_plan', 'farm_quantity'])) {
return;
}
// If this is a "By type" display and a bundle argument is specified, load
// the bundle label and set the title.
$bundle = FALSE;
if ($view->current_display == 'page_type' && !empty($view->args[0])) {
$bundle = $view->args[0];
}
elseif ($view->id() == 'farm_log' && $view->current_display == 'page_asset' && !empty($view->args[1]) && $view->args[1] != 'all') {
$bundle = $view->args[1];
}
if (!empty($bundle)) {
$bundles = \Drupal::service('entity_type.bundle.info')->getBundleInfo($view->getBaseEntityType()->id());
if (!empty($bundles[$bundle])) {
$view->setTitle($bundles[$bundle]['label'] . ' ' . $view->getBaseEntityType()->getPluralLabel());
}
}
}
/**
* Helper function for adding bundle-specific field and filter handlers.
*
* @param \Drupal\views\ViewExecutable $view
* The View to add handlers to.
* @param string $display_id
* The ID of the View display to add handlers to.
* @param string $bundle
* The bundle name.
* @param string $type
* The handler type ('field' or 'filter').
*/
function farm_ui_views_add_bundle_handlers(ViewExecutable $view, string $display_id, string $bundle, string $type) {
// Get the entity and bundle.
$base_entity = $view->getBaseEntityType();
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = \Drupal::entityTypeManager()->getStorage($base_entity->id())->getTableMapping();
// Load bundle fields.
/** @var \Drupal\entity\BundleFieldDefinition[] $bundle_fields */
$bundle_fields = \Drupal::entityTypeManager()->getHandler($base_entity->id(), 'bundle_plugin')->getFieldDefinitions($bundle);
foreach (array_reverse($bundle_fields) as $field_name => $field_definition) {
// Skip the bundle field if the view display was set as "hidden".
$view_options = $field_definition->getDisplayOptions('view');
if (empty($view_options) || (!empty($view_options['region']) && $view_options['region'] == 'hidden')) {
continue;
}
// Save the field type.
$field_type = $field_definition->getType();
// Get the field's table column (main property name).
$table = $table_mapping->getFieldTableName($field_name);
$property_name = $field_definition->getFieldStorageDefinition()->getMainPropertyName();
// Build the column and table names.
$column_name = $field_name . '_' . $property_name;
$views_option_name = $table . '.' . $column_name;
// Add a field handler if a views data field definition exists.
if ($type == 'field') {
$field_options = Views::viewsDataHelper()->fetchFields($table, 'field');
if (isset($field_options[$views_option_name])) {
// Build field options for the field type.
$field_options = [];
switch ($field_type) {
case 'entity_reference':
$target_type = $field_definition->getSetting('target_type');
// Do not render a link to referenced taxonomy terms.
if ($target_type === 'taxonomy_term') {
$field_options['type'] = 'entity_reference_label';
$field_options['settings']['link'] = FALSE;
}
break;
case 'timestamp':
// Render timestamp fields in the html_date format.
$field_options['type'] = 'timestamp';
$field_options['settings']['date_format'] = 'html_date';
break;
}
// Add the field handler.
$new_field_id = $view->addHandler($display_id, 'field', $table, $column_name, $field_options);
// Determine what position to insert the field handler.
switch ($base_entity->id()) {
case 'asset':
case 'plan':
$sort_field = 'name';
break;
case 'log':
$sort_field = 'quantity_target_id';
break;
case 'quantity':
default:
$sort_field = FALSE;
break;
}
// Sort the field handlers if necessary.
if (!empty($sort_field)) {
farm_ui_views_sort_field($view, $display_id, $new_field_id, $sort_field);
}
}
}
// Add a filter handler if a views data filter definition exists.
elseif ($type == 'filter') {
$filter_options = Views::viewsDataHelper()->fetchFields($table, 'filter');
if (isset($filter_options[$views_option_name])) {
$filter_options = [
'id' => $field_name,
'table' => $table,
'field' => $column_name,
'exposed' => TRUE,
'expose' => [
'operator_id' => $column_name . '_op',
'label' => $filter_options[$views_option_name]['title'],
'identifier' => $column_name,
'multiple' => TRUE,
],
'entity_type' => $base_entity->id(),
'entity_field' => $field_name,
];
// Build filter options for the field type.
switch ($field_type) {
case 'entity_reference':
$target_type = $field_definition->getSetting('target_type');
// Use a select widget for taxonomy term references.
if ($target_type === 'taxonomy_term') {
$filter_options['type'] = 'select';
// Limit to specific vocabularies if configured.
$handler_settings = $field_definition->getSetting('handler_settings');
$filter_options['limit'] = FALSE;
if (!empty($handler_settings['target_bundles'])) {
$filter_options['limit'] = TRUE;
$filter_options['vid'] = reset($handler_settings['target_bundles']);
}
}
break;
case 'string':
// String fields use the contains operator.
$filter_options['operator'] = 'contains';
break;
}
// Add the filter handler.
$view->addHandler($display_id, 'filter', $table, $column_name, $filter_options);
}
}
}
}