mirror of
https://github.com/farmOS/farmOS.git
synced 2024-02-23 11:37:38 +01:00
305 lines
11 KiB
PHP
305 lines
11 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file
|
|
* The farmOS UI Views module.
|
|
*/
|
|
|
|
use Drupal\Core\Entity\EntityTypeInterface;
|
|
use Drupal\views\ViewExecutable;
|
|
use Drupal\views\Views;
|
|
|
|
/**
|
|
* Implements hook_farm_dashboard_panes().
|
|
*/
|
|
function farm_ui_views_farm_dashboard_panes() {
|
|
$panes = [];
|
|
|
|
// If the plan module is enabled, add active plans pane.
|
|
if (\Drupal::service('module_handler')->moduleExists('plan')) {
|
|
$panes['active_plans'] = [
|
|
'view' => 'farm_plan',
|
|
'view_display_id' => 'block_active',
|
|
'group' => 'plans',
|
|
'weight' => 0,
|
|
];
|
|
}
|
|
|
|
// Add upcoming and late logs panes.
|
|
$panes['upcoming_tasks'] = [
|
|
'view' => 'farm_log',
|
|
'view_display_id' => 'block_upcoming',
|
|
'group' => 'logs',
|
|
'weight' => 10,
|
|
];
|
|
$panes['late_tasks'] = [
|
|
'view' => 'farm_log',
|
|
'view_display_id' => 'block_late',
|
|
'group' => 'logs',
|
|
'weight' => 11,
|
|
];
|
|
|
|
return $panes;
|
|
}
|
|
|
|
/**
|
|
* Implements hook_entity_base_field_info_alter().
|
|
*/
|
|
function farm_ui_views_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
|
|
|
|
// Use Entity Browser widget for certain asset reference fields.
|
|
$alter_fields = [
|
|
'log' => [
|
|
'asset',
|
|
],
|
|
'quantity' => [
|
|
'inventory_asset',
|
|
],
|
|
];
|
|
foreach ($alter_fields as $entity_type_id => $field_names) {
|
|
if ($entity_type->id() != $entity_type_id) {
|
|
continue;
|
|
}
|
|
foreach ($field_names as $field_name) {
|
|
if (!empty($fields[$field_name])) {
|
|
/** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
|
|
$form_display_options = $fields[$field_name]->getDisplayOptions('form');
|
|
$form_display_options['type'] = 'entity_browser_entity_reference';
|
|
$form_display_options['settings'] = [
|
|
'entity_browser' => 'farm_asset',
|
|
'field_widget_display' => 'label',
|
|
'field_widget_remove' => TRUE,
|
|
'open' => TRUE,
|
|
'selection_mode' => 'selection_append',
|
|
'field_widget_edit' => FALSE,
|
|
'field_widget_replace' => FALSE,
|
|
'field_widget_display_settings' => [],
|
|
];
|
|
$fields[$field_name]->setDisplayOptions('form', $form_display_options);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
// Only alter the "By type" display if a type is provided.
|
|
if ($display_id == 'page_type' && !empty($args[0])) {
|
|
|
|
// 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, 'page_type', $view->args[0], 'field');
|
|
farm_ui_views_add_bundle_handlers($view, 'page_type', $view->args[0], '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) {
|
|
|
|
// 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.
|
|
// Based off the \Drupal\views_ui\Form\Ajax\Rearrange.php method of
|
|
// ordering handlers in views.
|
|
if (!empty($sort_field)) {
|
|
|
|
// Get the existing field handlers.
|
|
$type = 'field';
|
|
$types = ViewExecutable::getHandlerTypes();
|
|
$display = $view->displayHandlers->get($display_id);
|
|
$field_handlers = $display->getOption($types[$type]['plural']);
|
|
|
|
// Define the new field handler and insert at desired position.
|
|
$new_field_handler = [$new_field_id => $field_handlers[$new_field_id]];
|
|
$keys = array_keys($field_handlers);
|
|
$index = array_search($sort_field, $keys, TRUE);
|
|
$pos = empty($index) ? count($field_handlers) : $index + 1;
|
|
$new_field_handlers = array_merge(array_slice($field_handlers, 0, $pos, TRUE), $new_field_handler, array_slice($field_handlers, $pos));
|
|
|
|
// Set the display to use the sorted field handlers.
|
|
$display->setOption($types[$type]['plural'], $new_field_handlers);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 the "By type" display and a bundle argument is specified, load
|
|
// the bundle label and set the title.
|
|
if ($view->current_display == 'page_type' && !empty($view->args[0])) {
|
|
$bundles = \Drupal::service('entity_type.bundle.info')->getBundleInfo($view->getBaseEntityType()->id());
|
|
$bundle = $view->args[0];
|
|
if (!empty($bundles[$bundle])) {
|
|
$view->setTitle($bundles[$bundle]['label'] . ' ' . $view->getBaseEntityType()->getPluralLabel());
|
|
}
|
|
}
|
|
}
|