mirror of
https://github.com/farmOS/farmOS.git
synced 2024-02-23 11:37:38 +01:00
Issue #3217168: View of assets in location
This commit is contained in:
commit
b04d5eba6b
|
@ -13,6 +13,8 @@ determining an asset's location and geometry.
|
||||||
|
|
||||||
**Methods**:
|
**Methods**:
|
||||||
|
|
||||||
|
`isLocation($asset)` - Check if an asset is a location. Returns a boolean.
|
||||||
|
|
||||||
`isFixed($asset)` - Check if an asset is fixed. Returns a boolean.
|
`isFixed($asset)` - Check if an asset is fixed. Returns a boolean.
|
||||||
|
|
||||||
`hasLocation($asset)` - Check if an asset is located within other location
|
`hasLocation($asset)` - Check if an asset is located within other location
|
||||||
|
|
|
@ -68,6 +68,9 @@ function farm_location_views_data_alter(array &$data) {
|
||||||
'id' => 'asset_location',
|
'id' => 'asset_location',
|
||||||
'field_name' => 'location',
|
'field_name' => 'location',
|
||||||
],
|
],
|
||||||
|
'argument' => [
|
||||||
|
'id' => 'asset_location',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,13 @@ class AssetLocation implements AssetLocationInterface {
|
||||||
*/
|
*/
|
||||||
const ASSET_FIELD_GEOMETRY = 'intrinsic_geometry';
|
const ASSET_FIELD_GEOMETRY = 'intrinsic_geometry';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the asset boolean location field.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const ASSET_FIELD_LOCATION = 'is_location';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the asset boolean fixed field.
|
* The name of the asset boolean fixed field.
|
||||||
*
|
*
|
||||||
|
@ -99,6 +106,13 @@ class AssetLocation implements AssetLocationInterface {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isLocation(AssetInterface $asset): bool {
|
||||||
|
return !empty($asset->{static::ASSET_FIELD_LOCATION}->value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -10,6 +10,17 @@ use Drupal\log\Entity\LogInterface;
|
||||||
*/
|
*/
|
||||||
interface AssetLocationInterface {
|
interface AssetLocationInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an asset is a location.
|
||||||
|
*
|
||||||
|
* @param \Drupal\asset\Entity\AssetInterface $asset
|
||||||
|
* The Asset entity.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* Returns TRUE if it is a location, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public function isLocation(AssetInterface $asset): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an asset is fixed.
|
* Check if an asset is fixed.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\farm_location\Plugin\views\argument;
|
||||||
|
|
||||||
|
use Drupal\views\Plugin\views\argument\ArgumentPluginBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An argument for filtering assets by their current location.
|
||||||
|
*
|
||||||
|
* @ingroup views_argument_handlers
|
||||||
|
*
|
||||||
|
* @ViewsArgument("asset_location")
|
||||||
|
*/
|
||||||
|
class AssetLocation extends ArgumentPluginBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function query($group_by = FALSE) {
|
||||||
|
|
||||||
|
// First query for a list of asset IDs in the location, then use this list
|
||||||
|
// to filter the current View.
|
||||||
|
// We do this in two separate queries for a few reasons:
|
||||||
|
// 1. The Drupal and Views query APIs do not support the kind of compound
|
||||||
|
// JOIN that we use in the asset.location service's getAssetsByLocation().
|
||||||
|
// 2. We need to allow other modules to override the asset.location service
|
||||||
|
// to provide their own location logic (eg: the Group asset module). They
|
||||||
|
// shouldn't have to override this Views argument handler as well.
|
||||||
|
// 3. It keeps this Views argument handler's query modifications very
|
||||||
|
// simple. It only needs the condition: "WHERE asset.id IN (:asset_ids)".
|
||||||
|
// See https://www.drupal.org/project/farm/issues/3217168 for more info.
|
||||||
|
$location = \Drupal::entityTypeManager()->getStorage('asset')->load($this->argument);
|
||||||
|
$assets = \Drupal::service('asset.location')->getAssetsByLocation($location);
|
||||||
|
$asset_ids = [];
|
||||||
|
foreach ($assets as $asset) {
|
||||||
|
$asset_ids[] = $asset->id();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter to only include assets with those IDs.
|
||||||
|
$this->ensureMyTable();
|
||||||
|
$this->query->addWhere(0, "$this->tableAlias.id", $asset_ids, 'IN');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1063,7 +1063,7 @@ display:
|
||||||
display_plugin: rest_export
|
display_plugin: rest_export
|
||||||
id: csv
|
id: csv
|
||||||
display_title: 'CSV export (rest)'
|
display_title: 'CSV export (rest)'
|
||||||
position: 4
|
position: 5
|
||||||
display_options:
|
display_options:
|
||||||
display_extenders: { }
|
display_extenders: { }
|
||||||
style:
|
style:
|
||||||
|
@ -1118,7 +1118,7 @@ display:
|
||||||
display_plugin: entity_browser
|
display_plugin: entity_browser
|
||||||
id: entity_browser
|
id: entity_browser
|
||||||
display_title: 'Entity browser'
|
display_title: 'Entity browser'
|
||||||
position: 4
|
position: 6
|
||||||
display_options:
|
display_options:
|
||||||
display_extenders: { }
|
display_extenders: { }
|
||||||
defaults:
|
defaults:
|
||||||
|
@ -1608,7 +1608,7 @@ display:
|
||||||
display_plugin: page
|
display_plugin: page
|
||||||
id: page_children
|
id: page_children
|
||||||
display_title: 'Children (page)'
|
display_title: 'Children (page)'
|
||||||
position: 3
|
position: 4
|
||||||
display_options:
|
display_options:
|
||||||
display_extenders: { }
|
display_extenders: { }
|
||||||
display_description: ''
|
display_description: ''
|
||||||
|
@ -1680,6 +1680,70 @@ display:
|
||||||
- url.query_args
|
- url.query_args
|
||||||
- user.permissions
|
- user.permissions
|
||||||
tags: { }
|
tags: { }
|
||||||
|
page_location:
|
||||||
|
display_plugin: page
|
||||||
|
id: page_location
|
||||||
|
display_title: 'By location (page)'
|
||||||
|
position: 3
|
||||||
|
display_options:
|
||||||
|
display_extenders: { }
|
||||||
|
display_description: ''
|
||||||
|
path: asset/%asset/assets
|
||||||
|
arguments:
|
||||||
|
location:
|
||||||
|
id: location
|
||||||
|
table: asset
|
||||||
|
field: location
|
||||||
|
relationship: none
|
||||||
|
group_type: group
|
||||||
|
admin_label: ''
|
||||||
|
default_action: empty
|
||||||
|
exception:
|
||||||
|
value: all
|
||||||
|
title_enable: false
|
||||||
|
title: All
|
||||||
|
title_enable: false
|
||||||
|
title: ''
|
||||||
|
default_argument_type: fixed
|
||||||
|
default_argument_options:
|
||||||
|
argument: ''
|
||||||
|
default_argument_skip_url: false
|
||||||
|
summary_options:
|
||||||
|
base_path: ''
|
||||||
|
count: true
|
||||||
|
items_per_page: 25
|
||||||
|
override: false
|
||||||
|
summary:
|
||||||
|
sort_order: asc
|
||||||
|
number_of_records: 0
|
||||||
|
format: default_summary
|
||||||
|
specify_validation: false
|
||||||
|
validate:
|
||||||
|
type: none
|
||||||
|
fail: 'not found'
|
||||||
|
validate_options: { }
|
||||||
|
entity_type: asset
|
||||||
|
plugin_id: asset_location
|
||||||
|
defaults:
|
||||||
|
arguments: false
|
||||||
|
menu:
|
||||||
|
type: tab
|
||||||
|
title: Assets
|
||||||
|
description: ''
|
||||||
|
expanded: false
|
||||||
|
parent: ''
|
||||||
|
weight: 50
|
||||||
|
context: '0'
|
||||||
|
menu_name: main
|
||||||
|
cache_metadata:
|
||||||
|
max-age: 0
|
||||||
|
contexts:
|
||||||
|
- 'languages:language_content'
|
||||||
|
- 'languages:language_interface'
|
||||||
|
- url
|
||||||
|
- url.query_args
|
||||||
|
- user.permissions
|
||||||
|
tags: { }
|
||||||
page_type:
|
page_type:
|
||||||
display_plugin: page
|
display_plugin: page
|
||||||
id: page_type
|
id: page_type
|
||||||
|
|
|
@ -8,3 +8,8 @@ services:
|
||||||
arguments: ['@entity_type.manager']
|
arguments: ['@entity_type.manager']
|
||||||
tags:
|
tags:
|
||||||
- { name: access_check, applies_to: _asset_logs_access }
|
- { name: access_check, applies_to: _asset_logs_access }
|
||||||
|
farm_ui_views.location_assets_access:
|
||||||
|
class: Drupal\farm_ui_views\Access\FarmLocationAssetViewsAccessCheck
|
||||||
|
arguments: [ '@entity_type.manager', '@asset.location' ]
|
||||||
|
tags:
|
||||||
|
- { name: access_check, applies_to: _location_assets_access }
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\farm_ui_views\Access;
|
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||||
|
use Drupal\Core\Routing\Access\AccessInterface;
|
||||||
|
use Drupal\Core\Routing\RouteMatchInterface;
|
||||||
|
use Drupal\Core\Access\AccessResult;
|
||||||
|
use Drupal\farm_location\AssetLocationInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks access for displaying Views of assets in a location.
|
||||||
|
*/
|
||||||
|
class FarmLocationAssetViewsAccessCheck implements AccessInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The asset storage.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Entity\EntityStorageInterface
|
||||||
|
*/
|
||||||
|
protected $assetStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The asset location service.
|
||||||
|
*
|
||||||
|
* @var \Drupal\farm_location\AssetLocationInterface
|
||||||
|
*/
|
||||||
|
protected $assetLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FarmLocationAssetViewsAccessCheck constructor.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||||
|
* The entity type manager service.
|
||||||
|
* @param \Drupal\farm_location\AssetLocationInterface $asset_location
|
||||||
|
* The asset location service.
|
||||||
|
*/
|
||||||
|
public function __construct(EntityTypeManagerInterface $entity_type_manager, AssetLocationInterface $asset_location) {
|
||||||
|
$this->assetStorage = $entity_type_manager->getStorage('asset');
|
||||||
|
$this->assetLocation = $asset_location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom access check.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||||
|
* The route match.
|
||||||
|
*/
|
||||||
|
public function access(RouteMatchInterface $route_match) {
|
||||||
|
|
||||||
|
// If there is no "asset" parameter, bail.
|
||||||
|
$asset_id = $route_match->getParameter('asset');
|
||||||
|
if (empty($asset_id)) {
|
||||||
|
return AccessResult::allowed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow access if the asset is a location.
|
||||||
|
/** @var \Drupal\asset\Entity\AssetInterface $asset */
|
||||||
|
$asset = $this->assetStorage->load($asset_id);
|
||||||
|
$access = AccessResult::allowedIf($this->assetLocation->isLocation($asset));
|
||||||
|
|
||||||
|
// Invalidate the access result when assets are changed.
|
||||||
|
$access->addCacheTags(["asset_list"]);
|
||||||
|
return $access;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,6 +21,12 @@ class RouteSubscriber extends RouteSubscriberBase {
|
||||||
if ($route = $collection->get('view.farm_log.page_asset')) {
|
if ($route = $collection->get('view.farm_log.page_asset')) {
|
||||||
$route->setRequirement('_asset_logs_access', 'Drupal\farm_ui_views\Access\FarmAssetLogViewsAccessCheck::access');
|
$route->setRequirement('_asset_logs_access', 'Drupal\farm_ui_views\Access\FarmAssetLogViewsAccessCheck::access');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add our _location_assets_access requirement to
|
||||||
|
// view.farm_asset.page_location.
|
||||||
|
if ($route = $collection->get('view.farm_asset.page_location')) {
|
||||||
|
$route->setRequirement('_location_assets_access', 'Drupal\farm_ui_views\Access\FarmLocationAssetViewsAccessCheck::access');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue