|
|
|
|
@ -5,7 +5,6 @@ namespace Drupal\metadata_profile\Controller;
|
|
|
|
|
use Drupal\Core\Config\Config; |
|
|
|
|
use Drupal\Core\Config\ConfigFactoryInterface; |
|
|
|
|
use Drupal\Core\Controller\ControllerBase; |
|
|
|
|
use Drupal\Core\Entity\ContentEntityForm; |
|
|
|
|
use Drupal\Core\Entity\EntityFieldManagerInterface; |
|
|
|
|
use Drupal\Core\Field\BaseFieldDefinition; |
|
|
|
|
use Drupal\Core\Field\FieldDefinitionInterface; |
|
|
|
|
@ -15,13 +14,14 @@ use Drupal\Core\Link;
|
|
|
|
|
use Drupal\Core\Messenger\MessengerTrait; |
|
|
|
|
use Drupal\Core\Routing\RouteMatchInterface; |
|
|
|
|
use Drupal\Core\Url; |
|
|
|
|
use Drupal\node\NodeForm; |
|
|
|
|
use Drupal\system\FileDownloadController; |
|
|
|
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
|
|
|
|
use Symfony\Component\HttpFoundation\Request; |
|
|
|
|
|
|
|
|
|
use Drupal\Core\Database\Connection; |
|
|
|
|
use Drupal\Core\Entity\EntityTypeManagerInterface; |
|
|
|
|
|
|
|
|
|
class MetadataProfileController extends ControllerBase { |
|
|
|
|
|
|
|
|
|
use MessengerTrait; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
@ -79,6 +79,7 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
* @var \Drupal\Core\File\FileSystemInterface |
|
|
|
|
*/ |
|
|
|
|
protected $fileSystem; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The file download controller. |
|
|
|
|
* |
|
|
|
|
@ -86,13 +87,30 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
*/ |
|
|
|
|
protected $fileDownloadController; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The Database connection. |
|
|
|
|
* |
|
|
|
|
* @var \Drupal\Core\Database\Connection |
|
|
|
|
*/ |
|
|
|
|
protected Connection $database; |
|
|
|
|
|
|
|
|
|
public function __construct(EntityFieldManagerInterface $entity_field_manager, |
|
|
|
|
FieldTypePluginManagerInterface $field_type_plugin_manager, |
|
|
|
|
ConfigFactoryInterface $config_factory, |
|
|
|
|
RouteMatchInterface $route_match, |
|
|
|
|
FileSystemInterface $file_system, |
|
|
|
|
FileDownloadController $file_download_controller) { |
|
|
|
|
/** |
|
|
|
|
* The Entity type manager. |
|
|
|
|
* |
|
|
|
|
* @var \Drupal\Core\Entity\EntityTypeManagerInterface |
|
|
|
|
*/ |
|
|
|
|
protected EntityTypeManagerInterface $entityTypeManagerService; |
|
|
|
|
|
|
|
|
|
public function __construct( |
|
|
|
|
EntityFieldManagerInterface $entity_field_manager, |
|
|
|
|
FieldTypePluginManagerInterface $field_type_plugin_manager, |
|
|
|
|
ConfigFactoryInterface $config_factory, |
|
|
|
|
RouteMatchInterface $route_match, |
|
|
|
|
FileSystemInterface $file_system, |
|
|
|
|
FileDownloadController $file_download_controller, |
|
|
|
|
Connection $database, |
|
|
|
|
EntityTypeManagerInterface $entity_type_manager // ✅ ADD THIS |
|
|
|
|
) { |
|
|
|
|
$this->entityFieldManager = $entity_field_manager; |
|
|
|
|
$this->fieldTypePluginManager = $field_type_plugin_manager; |
|
|
|
|
$this->configFactory = $config_factory; |
|
|
|
|
@ -105,6 +123,8 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
$this->entityTypeBundleOf = $entity_type->getEntityType()->getBundleOf(); |
|
|
|
|
$this->fileSystem = $file_system; |
|
|
|
|
$this->fileDownloadController = $file_download_controller; |
|
|
|
|
$this->database = $database; |
|
|
|
|
$this->entityTypeManagerService = $entity_type_manager; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static function create(ContainerInterface $container) { |
|
|
|
|
@ -114,7 +134,9 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
$container->get('config.factory'), |
|
|
|
|
$container->get('current_route_match'), |
|
|
|
|
$container->get('file_system'), |
|
|
|
|
FileDownloadController::create($container) |
|
|
|
|
FileDownloadController::create($container), |
|
|
|
|
$container->get('database'), |
|
|
|
|
$container->get('entity_type.manager'), |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -124,11 +146,10 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
* @return array |
|
|
|
|
*/ |
|
|
|
|
public function profile() { |
|
|
|
|
|
|
|
|
|
// Get core content type information. |
|
|
|
|
$bundle_config = $this->config(str_replace('_', '.', $this->entityType) . '.' . $this->entityBundle); |
|
|
|
|
$bundle_config = $this->config(str_replace('_', '.', $this->entityType) . '.' . $this->entityBundle); |
|
|
|
|
if (!$bundle_config) { |
|
|
|
|
return ['#markup'=> 'Not a valid content type.']; |
|
|
|
|
return ['#markup' => 'Not a valid content type.']; |
|
|
|
|
} |
|
|
|
|
$build = $this->formatBundle($bundle_config); |
|
|
|
|
|
|
|
|
|
@ -136,7 +157,7 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
|
|
|
|
|
$build['summary_table'] = [ |
|
|
|
|
'#type' => 'container', |
|
|
|
|
'#attributes'=> ['class' => ['scrolling-table-container']], |
|
|
|
|
'#attributes' => ['class' => ['scrolling-table-container']], |
|
|
|
|
'data' => $this->buildSummaryTable($metadata_profile), |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
@ -175,7 +196,7 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
'#type' => 'container', |
|
|
|
|
'#attached' => ['library' => ['metadata_profile/metadata_profile']], |
|
|
|
|
|
|
|
|
|
'title' => [ |
|
|
|
|
'title' => [ |
|
|
|
|
'#plain_text' => $label, |
|
|
|
|
'#prefix' => '<h1>', |
|
|
|
|
'#suffix' => '</h1>', |
|
|
|
|
@ -194,40 +215,73 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
return $build; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Builds a metadata profile for the current entity bundle. |
|
|
|
|
* |
|
|
|
|
* The returned array is keyed by field machine name and contains |
|
|
|
|
* structured metadata describing each field. |
|
|
|
|
* |
|
|
|
|
* Each field profile contains: |
|
|
|
|
* - label: string |
|
|
|
|
* - machine_name: string |
|
|
|
|
* - id: string |
|
|
|
|
* - edit_url: \Drupal\Core\Url|null |
|
|
|
|
* - details_link: \Drupal\Core\Link |
|
|
|
|
* - description: string |
|
|
|
|
* - type: string (human readable) |
|
|
|
|
* - type_machine_name: string |
|
|
|
|
* - required: render array |
|
|
|
|
* - repeatable: render array|string |
|
|
|
|
* - auto_create: render array|null |
|
|
|
|
* - target_bundles: array |
|
|
|
|
* - base_field: bool |
|
|
|
|
* - usage_count: int |
|
|
|
|
* - search_api: array |
|
|
|
|
* |
|
|
|
|
* @return array |
|
|
|
|
* Metadata profile keyed by field machine name. |
|
|
|
|
*/ |
|
|
|
|
public function getMetadataProfile() { |
|
|
|
|
// $metadata_profile is an array of arrays. Its keys are the "short" machine names of the fields |
|
|
|
|
// such as field_abstract. The values are arrays with the following keys: |
|
|
|
|
// * 'label' - text. the bundle's human-readable label. |
|
|
|
|
// * 'machine_name' - text. The short machine name such as 'field_abstract'. |
|
|
|
|
// * 'id' - text. The long machine name such as 'node.islandora_object.field_abstract'. (same as this array's key) |
|
|
|
|
// * 'edit_url' - Url object. The link to the edit page for that field (or to the base field override page). |
|
|
|
|
// * 'description' - the help text for the field. |
|
|
|
|
// * 'type' - text. The human readable type of the field. (e.g. "Entity Reference") |
|
|
|
|
// * 'type_machine_name' - text. The machine name of the type (e.g. 'entity_reference') |
|
|
|
|
// * 'required' - 'Required'|'Not required'. Whether the field is required. |
|
|
|
|
// * 'cardinality' - 'Not repeatable'|'Repeatable'|'Repeatable, limit N' |
|
|
|
|
// * 'auto_create' - 'Create new'|'Create new #bundle'|'Do not create new'|NULL Whether a relationship field allows new entity creation on the fly. |
|
|
|
|
// * 'target_bundles' - array. List of bundle names that are the target of this field. |
|
|
|
|
// * 'search_api' - associative array. Has the following keys: |
|
|
|
|
// * 'in_search_api' - True|False. True if some field matches. |
|
|
|
|
// * 'has_facet' - True|False. True if some field has a facet. |
|
|
|
|
// * 'fields' - array. The 'fields' array is keyed by the machine names of the search api fields, |
|
|
|
|
// which are arrays with the following fields: |
|
|
|
|
// * 'search_api_field_name' - the machine name of the search api field. |
|
|
|
|
// * 'search_api_field_label' - the human readable label of the search api field. |
|
|
|
|
// * 'property_path' - the method for getting the values. |
|
|
|
|
// * 'type' = the search api field type. |
|
|
|
|
// * 'index_name' - the name of the Search API index (in case there are more than one) |
|
|
|
|
// * 'fields_included' - for aggregate and EDTF processor fields, which fields are in that field. |
|
|
|
|
// * 'facets' - associative array. has the following keys |
|
|
|
|
// * 'has_facet' - True|False. True if there is a facet, even if not showing up (can use with url alias) |
|
|
|
|
// * 'facets' - array. the 'facets' array is keyed by the machine name of the facet. each facet is an |
|
|
|
|
// array with keys: |
|
|
|
|
// * 'facet_name' |
|
|
|
|
// * 'facet_machine_name' |
|
|
|
|
// * 'facet_source' |
|
|
|
|
// * 'url_alias' |
|
|
|
|
// * 'block_visible' -- not yet implemented. |
|
|
|
|
/** |
|
|
|
|
* Metadata profile structure. |
|
|
|
|
* |
|
|
|
|
* $metadata_profile is an associative array keyed by field machine names |
|
|
|
|
* (e.g. "field_abstract"). Each value is an array with the following keys: |
|
|
|
|
* |
|
|
|
|
* - label: (string) Human-readable field label. |
|
|
|
|
* - machine_name: (string) Short machine name (e.g. "field_abstract"). |
|
|
|
|
* - id: (string) Full machine name |
|
|
|
|
* (e.g. "node.islandora_object.field_abstract"). |
|
|
|
|
* - edit_url: (\Drupal\Core\Url) Link to edit the field configuration. |
|
|
|
|
* - description: (string) Field help text. |
|
|
|
|
* - type: (string) Human-readable field type (e.g. "Entity Reference"). |
|
|
|
|
* - type_machine_name: (string) Field type machine name |
|
|
|
|
* (e.g. "entity_reference"). |
|
|
|
|
* - required: (string) "Required" or "Not required". |
|
|
|
|
* - cardinality: (string) "Not repeatable", "Repeatable", |
|
|
|
|
* or "Repeatable, limit N". |
|
|
|
|
* - auto_create: (string|null) Whether referenced entities can be created: |
|
|
|
|
* "Create new", "Create new (bundle)", or "Do not create new". |
|
|
|
|
* - target_bundles: (string[]) List of allowed target bundles. |
|
|
|
|
* - search_api: (array) Search API metadata: |
|
|
|
|
* - in_search_api: (bool) TRUE if indexed. |
|
|
|
|
* - has_facet: (bool) TRUE if any facet exists. |
|
|
|
|
* - fields: (array) Indexed by Search API field machine name: |
|
|
|
|
* - search_api_field_name: (string) |
|
|
|
|
* - search_api_field_label: (string) |
|
|
|
|
* - property_path: (string) |
|
|
|
|
* - type: (string) |
|
|
|
|
* - index_name: (string) |
|
|
|
|
* - fields_included: (array) Included fields (aggregated/EDTF). |
|
|
|
|
* - facets: (array) Facet definitions: |
|
|
|
|
* - has_facet: (bool) |
|
|
|
|
* - facets: (array) Each facet contains: |
|
|
|
|
* - facet_name: (string) |
|
|
|
|
* - facet_machine_name: (string) |
|
|
|
|
* - facet_source: (string) |
|
|
|
|
* - url_alias: (string) |
|
|
|
|
* - block_visible: (string) Not yet implemented. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
$metadata_profile = []; |
|
|
|
|
$field_definitions = $this->entityFieldManager->getFieldDefinitions($this->entityTypeBundleOf, $this->entityBundle); |
|
|
|
|
@ -246,13 +300,27 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
'auto_create' => $this->formatCreateNew($field_definition), |
|
|
|
|
'target_bundles' => $this->formatTargetBundles($field_definition), |
|
|
|
|
'base_field' => $field_definition->getFieldStorageDefinition() instanceof BaseFieldDefinition, |
|
|
|
|
'usage_count' => $this->getUsageCount($field_name), |
|
|
|
|
]; |
|
|
|
|
$metadata_profile[$field_name]['search_api'] = $this->getSearchApi($field_definition); |
|
|
|
|
$metadata_profile[$field_name]['search_api'] = $this->getSearchApi($field_definition); |
|
|
|
|
} |
|
|
|
|
$metadata_profile = $this->addWeights($metadata_profile); |
|
|
|
|
return $metadata_profile; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Builds Search API metadata for a field definition. |
|
|
|
|
* |
|
|
|
|
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition |
|
|
|
|
* The field definition. |
|
|
|
|
* |
|
|
|
|
* @return array|false |
|
|
|
|
* An associative array containing: |
|
|
|
|
* - in_search_api: bool |
|
|
|
|
* - has_facet: bool |
|
|
|
|
* - fields: array |
|
|
|
|
* Or FALSE if Search API module is not enabled. |
|
|
|
|
*/ |
|
|
|
|
private function getSearchApi($field_definition) { |
|
|
|
|
if (!$this->moduleHandler()->moduleExists('search_api')) { |
|
|
|
|
return FALSE; |
|
|
|
|
@ -274,7 +342,7 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
|
|
|
|
|
// Loop over fields. |
|
|
|
|
foreach ($index_config->get('field_settings') as $search_api_field_name => $search_api_field_setting) { |
|
|
|
|
$indexed_field_name = $index_config->getName() . '.' .$search_api_field_name; |
|
|
|
|
$indexed_field_name = $index_config->getName() . '.' . $search_api_field_name; |
|
|
|
|
// Get Aggregated Fields. |
|
|
|
|
if ($search_api_field_setting['property_path'] == 'aggregated_field') { |
|
|
|
|
if (in_array('entity:node/' . $field_definition->getName(), $search_api_field_setting['configuration']['fields'])) { |
|
|
|
|
@ -282,19 +350,23 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Get EDTF fields. |
|
|
|
|
else if ($field_definition->getType() == 'edtf') { |
|
|
|
|
// Get EDTF year. |
|
|
|
|
if ($search_api_field_setting['property_path'] == 'edtf_year') { |
|
|
|
|
$edtf_year_fields = $index_config->get('processor_settings')['edtf_year_only']['fields'] ?: []; |
|
|
|
|
if (in_array(str_replace('.', '|', $field_definition->id()), $edtf_year_fields)) { |
|
|
|
|
$search_api['fields'][$indexed_field_name] = $this->getSearchApiField($search_api_field_name, $search_api_field_setting, $index_config); |
|
|
|
|
else { |
|
|
|
|
if ($field_definition->getType() == 'edtf') { |
|
|
|
|
// Get EDTF year. |
|
|
|
|
if ($search_api_field_setting['property_path'] == 'edtf_year') { |
|
|
|
|
$edtf_year_fields = $index_config->get('processor_settings')['edtf_year_only']['fields'] ?: []; |
|
|
|
|
if (in_array(str_replace('.', '|', $field_definition->id()), $edtf_year_fields)) { |
|
|
|
|
$search_api['fields'][$indexed_field_name] = $this->getSearchApiField($search_api_field_name, $search_api_field_setting, $index_config); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Get EDTF Date |
|
|
|
|
else if ($search_api_field_setting['property_path'] == 'edtf_dates') { |
|
|
|
|
$edtf_date_fields = $index_config->get('processor_settings')['edtf_date_processor']['fields'] ?: []; |
|
|
|
|
if (in_array(str_replace('.', '|', $field_definition->id()), $edtf_date_fields)) { |
|
|
|
|
$search_api['fields'][$indexed_field_name] = $this->getSearchApiField($search_api_field_name, $search_api_field_setting, $index_config); |
|
|
|
|
// Get EDTF Date |
|
|
|
|
else { |
|
|
|
|
if ($search_api_field_setting['property_path'] == 'edtf_dates') { |
|
|
|
|
$edtf_date_fields = $index_config->get('processor_settings')['edtf_date_processor']['fields'] ?: []; |
|
|
|
|
if (in_array(str_replace('.', '|', $field_definition->id()), $edtf_date_fields)) { |
|
|
|
|
$search_api['fields'][$indexed_field_name] = $this->getSearchApiField($search_api_field_name, $search_api_field_setting, $index_config); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -310,22 +382,29 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
if (isset($search_api_field_setting['datasource_id']) and $search_api_field_setting['property_path'] == $field_definition->getName()) { |
|
|
|
|
$search_api['fields'][$indexed_field_name] = $this->getSearchApiField($search_api_field_name, $search_api_field_setting, $index_config); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
if (count($search_api['fields']) > 0) { |
|
|
|
|
$search_api['in_search_api'] = TRUE; |
|
|
|
|
} |
|
|
|
|
if (in_array(TRUE, array_column($search_api['fields'], 'has_facet'), true)) { |
|
|
|
|
if (in_array(TRUE, array_column($search_api['fields'], 'has_facet'), TRUE)) { |
|
|
|
|
$search_api['has_facet'] = TRUE; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$search_api['has_facet'] = FALSE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
return $search_api; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Builds a render array for the summary table. |
|
|
|
|
* |
|
|
|
|
* @param array $metadata_profile |
|
|
|
|
* Metadata profile array. |
|
|
|
|
* |
|
|
|
|
* @return array |
|
|
|
|
* Render array for a Drupal table. |
|
|
|
|
*/ |
|
|
|
|
protected function buildSummaryTable($metadata_profile) { |
|
|
|
|
$rows = $this->getRows($metadata_profile, TRUE); |
|
|
|
|
return [ |
|
|
|
|
@ -333,13 +412,43 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
'#header' => $this->getHeaders(), |
|
|
|
|
'#rows' => $rows, |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function getRows($metadata_profile, $display=NULL) { |
|
|
|
|
/** |
|
|
|
|
* Builds table rows from a metadata profile array. |
|
|
|
|
* |
|
|
|
|
* Each row is a numerically indexed array representing a table row: |
|
|
|
|
* 0 => Field label or link |
|
|
|
|
* 1 => Machine name |
|
|
|
|
* 2 => Description |
|
|
|
|
* 3 => Field type (human readable) |
|
|
|
|
* 4 => Required indicator (render array) |
|
|
|
|
* 5 => Repeatable indicator (render array) |
|
|
|
|
* 6 => Auto-create indicator (render array|null) |
|
|
|
|
* 7 => In Search API (render array) |
|
|
|
|
* 8 => Has Facet (render array) |
|
|
|
|
* 9 => Target bundles (array|string|render array) |
|
|
|
|
* 10 => Weight (int|float) |
|
|
|
|
* 11 => Usage count (int) |
|
|
|
|
* |
|
|
|
|
* Rows are sorted descending by usage count (index 11). |
|
|
|
|
* |
|
|
|
|
* @param array $metadata_profile |
|
|
|
|
* Structured metadata profile keyed by field machine name. |
|
|
|
|
* @param bool|null $display |
|
|
|
|
* Whether to return renderable values (TRUE) or raw values (FALSE/NULL). |
|
|
|
|
* |
|
|
|
|
* @return array |
|
|
|
|
* A numerically indexed array of row arrays. |
|
|
|
|
*/ |
|
|
|
|
protected function getRows($metadata_profile, $display = NULL) { |
|
|
|
|
$rows = []; |
|
|
|
|
foreach ($metadata_profile as $field_name => $field_profile) { |
|
|
|
|
if (str_starts_with( $field_name, 'field_') or in_array($field_name, ['title', 'name'])) { |
|
|
|
|
if (str_starts_with($field_name, 'field_') or in_array($field_name, [ |
|
|
|
|
'title', |
|
|
|
|
'name', |
|
|
|
|
])) { |
|
|
|
|
$bundles = $field_profile['target_bundles'] ?? []; |
|
|
|
|
$rows[] = [ |
|
|
|
|
$display ? $field_profile['details_link'] : $field_profile['label'], |
|
|
|
|
$field_profile['machine_name'], |
|
|
|
|
@ -348,13 +457,20 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
$field_profile['required'], |
|
|
|
|
$field_profile['repeatable'], |
|
|
|
|
$field_profile['auto_create'], |
|
|
|
|
$display ? $this->formatListForTable($field_profile['target_bundles']) : $field_profile['target_bundles'], |
|
|
|
|
$field_profile['search_api']['in_search_api'] ? 'Indexed' : '', |
|
|
|
|
$field_profile['search_api']['has_facet'] ? 'Facet' : '', |
|
|
|
|
|
|
|
|
|
$this->yesNoIcon($field_profile['search_api']['in_search_api']), |
|
|
|
|
$this->YesNoIcon($field_profile['search_api']['has_facet']), |
|
|
|
|
$display |
|
|
|
|
? $this->formatListForTable($bundles) |
|
|
|
|
: $bundles, |
|
|
|
|
$field_profile['weight'], |
|
|
|
|
]; |
|
|
|
|
$field_profile['usage_count'], |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
usort($rows, function($a, $b) { |
|
|
|
|
return $b[11] <=> $a[11]; |
|
|
|
|
}); |
|
|
|
|
return $rows; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -367,10 +483,11 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
$this->t('Required'), |
|
|
|
|
$this->t('Repeatable'), |
|
|
|
|
$this->t('Create new'), |
|
|
|
|
$this->t('Target bundles'), |
|
|
|
|
$this->t('In Search API'), |
|
|
|
|
$this->t('Has Facet'), |
|
|
|
|
$this->t('Target bundles'), |
|
|
|
|
$this->t('Weight'), |
|
|
|
|
$this->t("Usage count"), |
|
|
|
|
|
|
|
|
|
// TODO: add more columns |
|
|
|
|
]; |
|
|
|
|
@ -379,7 +496,10 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
protected function buildField(array $field_profile) { |
|
|
|
|
$render_array = []; |
|
|
|
|
$field_name = $field_profile['machine_name']; |
|
|
|
|
if (str_starts_with($field_name, 'field_') or in_array($field_name, ['title', 'name'])) { |
|
|
|
|
if (str_starts_with($field_name, 'field_') or in_array($field_name, [ |
|
|
|
|
'title', |
|
|
|
|
'name', |
|
|
|
|
])) { |
|
|
|
|
$render_array = [ |
|
|
|
|
'#type' => 'container', |
|
|
|
|
'#attributes' => ['class' => ['field-info']], |
|
|
|
|
@ -395,10 +515,20 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
'#prefix' => '(', |
|
|
|
|
'#suffix' => ') ', |
|
|
|
|
], |
|
|
|
|
'usage_count' => [ |
|
|
|
|
'#markup' => $this->formatPlural( |
|
|
|
|
$field_profile['usage_count'], |
|
|
|
|
"Used <strong>1</strong> time.", |
|
|
|
|
"Used <strong>@count</strong> times." |
|
|
|
|
), |
|
|
|
|
'#prefix' => '</ br>', |
|
|
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
|
|
'edit_link' => $field_profile['edit_url'] ? $this->formatFieldEditLink($field_profile['edit_url']) : [], |
|
|
|
|
'table' => [ |
|
|
|
|
'#type' => 'table', |
|
|
|
|
'#header' => ['Field Configuration',''], |
|
|
|
|
'#header' => ['Field Configuration', ''], |
|
|
|
|
'#rows' => $this->getFieldTableRows($field_profile), |
|
|
|
|
'#attributes' => ['class' => ['field-info-table']], |
|
|
|
|
'#prefix' => '<h3>' . $this->t('Field Information') . '</h3>', |
|
|
|
|
@ -411,9 +541,6 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
'search_api' => $this->formatSearchApi($field_profile), |
|
|
|
|
'facets' => $this->formatFacets($field_profile), |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $render_array; |
|
|
|
|
@ -427,7 +554,7 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
$edit_url = Url::fromRoute('entity.base_field_override.' . $this->entityTypeBundleOf . '_base_field_override_edit_form', [ |
|
|
|
|
$this->entityType => $field_definition->getTargetBundle(), |
|
|
|
|
'base_field_override' => $field_definition->id(), |
|
|
|
|
'destination' => $redirect_url->toString() |
|
|
|
|
'destination' => $redirect_url->toString(), |
|
|
|
|
]); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
@ -439,7 +566,7 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$edit_url = Url::fromRoute('entity.field_config.' . $this->entityTypeBundleOf . '_field_edit_form', [ |
|
|
|
|
$edit_url = Url::fromRoute('entity.field_config.' . $this->entityTypeBundleOf . '_field_edit_form', [ |
|
|
|
|
$this->entityType => $field_definition->getTargetBundle(), |
|
|
|
|
'field_config' => $field_definition->id(), |
|
|
|
|
'destination' => $redirect_url->toString(), |
|
|
|
|
@ -448,8 +575,7 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
return $edit_url; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function getFieldDetailsFragmentLink(string $field_name, FieldDefinitionInterface $field_definition) |
|
|
|
|
{ |
|
|
|
|
private function getFieldDetailsFragmentLink(string $field_name, FieldDefinitionInterface $field_definition) { |
|
|
|
|
$url = Url::fromRoute('<current>', [], ['fragment' => $field_name]); |
|
|
|
|
return Link::fromTextAndUrl($field_definition->getLabel(), $url); |
|
|
|
|
} |
|
|
|
|
@ -463,20 +589,21 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function getFieldTableRows(array $field_profile) { |
|
|
|
|
$rows = [ |
|
|
|
|
$rows = [ |
|
|
|
|
[$this->t('Type:'), $field_profile['type']], |
|
|
|
|
[$this->t('Required:'), $field_profile['required']], |
|
|
|
|
[$this->t('Repeatable:'), $field_profile['repeatable']], |
|
|
|
|
]; |
|
|
|
|
if ($field_profile['auto_create']) { |
|
|
|
|
$rows[] = [$this->t('Create new:'), $field_profile['auto_create']]; |
|
|
|
|
} |
|
|
|
|
if ($field_profile['target_bundles']) { |
|
|
|
|
$rows[] = [ |
|
|
|
|
$this->t('Target bundles:'), |
|
|
|
|
$this->formatListForTable($field_profile['target_bundles']), |
|
|
|
|
]; |
|
|
|
|
if ($field_profile['auto_create']) { |
|
|
|
|
$rows[] = [$this->t('Create new:'), $field_profile['auto_create']]; |
|
|
|
|
} |
|
|
|
|
if ($field_profile['target_bundles']) { |
|
|
|
|
$rows[] = [$this->t('Target bundles:'), $this->formatListForTable($field_profile['target_bundles'])]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $rows; |
|
|
|
|
} |
|
|
|
|
@ -489,24 +616,22 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
} |
|
|
|
|
return $type_label; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function formatRequired(FieldDefinitionInterface $field_definition) { |
|
|
|
|
if ($field_definition->isRequired()) { |
|
|
|
|
return $this->t('Required'); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
return $this->t('Not required'); |
|
|
|
|
} |
|
|
|
|
$cardinality = $field_definition->isRequired(); |
|
|
|
|
return $this->yesNoIcon($cardinality); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* This does not work - most fields dont have a form weight specified in getDisplayOptions. |
|
|
|
|
* This does not work - most fields dont have a form weight specified in |
|
|
|
|
* getDisplayOptions. |
|
|
|
|
*/ |
|
|
|
|
protected function getWeight(string $field_name, array $form) { |
|
|
|
|
if (isset($form[$field_name])) { |
|
|
|
|
$local_weight = $form[$field_name]['#weight']; |
|
|
|
|
if ($parent = $form['#group_children'][$field_name]) { |
|
|
|
|
$parent_weight = $this->getWeight($parent, $form); |
|
|
|
|
return $this->combine_weights($parent_weight, $local_weight); |
|
|
|
|
return $this->combineWeights($parent_weight, $local_weight); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
return $local_weight; |
|
|
|
|
@ -518,32 +643,35 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function formatCardinality(FieldDefinitionInterface $field_definition) { |
|
|
|
|
$cardinality = $field_definition->getFieldStorageDefinition()->getCardinality(); |
|
|
|
|
if ($cardinality == 1) { |
|
|
|
|
return $this->t('Not repeatable'); |
|
|
|
|
} elseif ($cardinality < 0) { |
|
|
|
|
return $this->t('Repeatable'); |
|
|
|
|
} elseif ($cardinality > 1) { |
|
|
|
|
return $this->t('Repeatable, limit :limit', [':limit' => $cardinality]); |
|
|
|
|
$cardinality = $field_definition |
|
|
|
|
->getFieldStorageDefinition() |
|
|
|
|
->getCardinality(); |
|
|
|
|
|
|
|
|
|
if ($cardinality === 1) { |
|
|
|
|
return $this->yesNoIcon($cardinality); |
|
|
|
|
} |
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
if ($cardinality === -1) { |
|
|
|
|
return $this->yesNoIcon($cardinality); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $this->t('Yes (max @limit)', [ |
|
|
|
|
'@limit' => $cardinality, |
|
|
|
|
]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function formatCreateNew(FieldDefinitionInterface $field_definition) { |
|
|
|
|
if (in_array($field_definition->getType(), ['entity_reference', 'typed_relation'])) { |
|
|
|
|
$create_new_bundle = $field_definition->getSetting('handler_settings')['auto_create_bundle'] ? $create_new_bundle = $field_definition->getSetting('handler_settings')['auto_create_bundle'] : ''; |
|
|
|
|
$create_new = $field_definition->getSetting('handler_settings')['auto_create'] || ''; |
|
|
|
|
if ($create_new) { |
|
|
|
|
return $create_new_bundle ? 'Create new (' . $create_new_bundle . ')' : 'Create new'; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
return $this->t('Do not create new'); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
if (!in_array($field_definition->getType(), [ |
|
|
|
|
'entity_reference', |
|
|
|
|
'typed_relation', |
|
|
|
|
], TRUE)) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$settings = $field_definition->getSetting('handler_settings') ?? []; |
|
|
|
|
$create_new = !empty($settings['auto_create']); |
|
|
|
|
|
|
|
|
|
return $this->yesNoIcon($create_new); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function formatTargetBundles(FieldDefinitionInterface $field_definition) { |
|
|
|
|
@ -555,10 +683,14 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
$target_bundles = $setting['target_bundles']; |
|
|
|
|
foreach ($target_bundles as $index => $bundle) { |
|
|
|
|
if ($handler == 'default:taxonomy_term') { |
|
|
|
|
$bundle_config = $this->entityTypeManager()->getStorage('taxonomy_vocabulary')->load($bundle); |
|
|
|
|
$bundle_config = $this->entityTypeManager() |
|
|
|
|
->getStorage('taxonomy_vocabulary') |
|
|
|
|
->load($bundle); |
|
|
|
|
} |
|
|
|
|
if ($handler == 'default:node') { |
|
|
|
|
$bundle_config = $this->entityTypeManager()->getStorage('node_type')->load($bundle); |
|
|
|
|
$bundle_config = $this->entityTypeManager() |
|
|
|
|
->getStorage('node_type') |
|
|
|
|
->load($bundle); |
|
|
|
|
} |
|
|
|
|
// TODO: ADD MEDIA, PARAGRAPHS ETC |
|
|
|
|
if ($bundle_config) { |
|
|
|
|
@ -571,16 +703,18 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
'#theme' => 'item_list', |
|
|
|
|
'#title' => $this->t('Target bundles:'), |
|
|
|
|
'#items' => $target_bundles, |
|
|
|
|
'#type' => 'ul' |
|
|
|
|
]; |
|
|
|
|
'#type' => 'ul', |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function formatListForTable(array $list) { |
|
|
|
|
return ['data' => [ |
|
|
|
|
'#theme' => 'item_list', |
|
|
|
|
'#items' => array_values($list), |
|
|
|
|
'#type' => 'ul', |
|
|
|
|
]]; |
|
|
|
|
return [ |
|
|
|
|
'data' => [ |
|
|
|
|
'#theme' => 'item_list', |
|
|
|
|
'#items' => array_values($list), |
|
|
|
|
'#type' => 'ul', |
|
|
|
|
], |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function formatSearchApi($field_profile) { |
|
|
|
|
@ -613,9 +747,8 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function getSearchApiField($field_setting_name, $field_setting, $index_config) { |
|
|
|
|
$search_api_field_array = [ |
|
|
|
|
$search_api_field_array = [ |
|
|
|
|
'search_api_field_name' => $field_setting_name, |
|
|
|
|
'search_api_field_label' => $field_setting['label'], |
|
|
|
|
'property_path' => $field_setting['property_path'], |
|
|
|
|
@ -626,24 +759,30 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
if ($field_setting['property_path'] == 'aggregated_field') { |
|
|
|
|
$search_api_field_array['fields_included'] = $field_setting['configuration']['fields']; |
|
|
|
|
} |
|
|
|
|
else if ($field_setting['property_path'] == 'edtf_year') { |
|
|
|
|
$search_api_field_array['fields_included'] = $index_config->get('processor_settings')['edtf_year_only']['fields']; |
|
|
|
|
} |
|
|
|
|
else if ($field_setting['property_path'] == 'edtf') { |
|
|
|
|
$search_api_field_array['fields_included'] = $index_config->get('processor_settings')['edtf_date_processor']['fields']; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$search_api_field_array['fields_included'] = []; |
|
|
|
|
if ($field_setting['property_path'] == 'edtf_year') { |
|
|
|
|
$search_api_field_array['fields_included'] = $index_config->get('processor_settings')['edtf_year_only']['fields']; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
if ($field_setting['property_path'] == 'edtf') { |
|
|
|
|
$search_api_field_array['fields_included'] = $index_config->get('processor_settings')['edtf_date_processor']['fields']; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$search_api_field_array['fields_included'] = []; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Get facet info. |
|
|
|
|
$search_api_field_array['has_facet'] = FALSE; |
|
|
|
|
if ($this->moduleHandler()->moduleExists('facets')) { |
|
|
|
|
$all_facets = \Drupal::entityTypeManager()->getStorage('facets_facet')->loadMultiple(); |
|
|
|
|
$all_facets = \Drupal::entityTypeManager() |
|
|
|
|
->getStorage('facets_facet') |
|
|
|
|
->loadMultiple(); |
|
|
|
|
foreach ($all_facets as $facet_id => $facet) { |
|
|
|
|
// If facet uses this solr field... then add it to the array. |
|
|
|
|
if ($facet->get('field_identifier') == $field_setting_name) { |
|
|
|
|
$search_api_field_array['has_facet'] = True; |
|
|
|
|
$search_api_field_array['has_facet'] = TRUE; |
|
|
|
|
$search_api_field_array['facets'][] = [ |
|
|
|
|
'field_identifier' => $facet->get('field_identifier'), |
|
|
|
|
'facet_name' => $facet->getName(), |
|
|
|
|
@ -661,6 +800,7 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
protected function getBlockVisible($facet) { |
|
|
|
|
return ''; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function formatSearchApiField($search_api_field_profile) { |
|
|
|
|
return [ |
|
|
|
|
'data' => [ |
|
|
|
|
@ -671,26 +811,48 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
$this->formatListForTable($search_api_field_profile['fields_included']), |
|
|
|
|
$search_api_field_profile['index_name'], |
|
|
|
|
$search_api_field_profile['has_facet'] ? 'True' : '', |
|
|
|
|
] |
|
|
|
|
], |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Sanitizes table rows for CSV export. |
|
|
|
|
* |
|
|
|
|
* Converts renderable elements and objects into scalar values: |
|
|
|
|
* - Link objects are converted to their text. |
|
|
|
|
* - Arrays are flattened into pipe-delimited strings. |
|
|
|
|
* |
|
|
|
|
* @param array $rows |
|
|
|
|
* A numerically indexed array of row arrays. |
|
|
|
|
* |
|
|
|
|
* @return array |
|
|
|
|
* Sanitized rows suitable for fputcsv(). |
|
|
|
|
*/ |
|
|
|
|
public function sanitizeRowsForCSV($rows) { |
|
|
|
|
foreach ($rows as $row_key => $row) { |
|
|
|
|
foreach ($row as $element_key => $element) { |
|
|
|
|
if ($element instanceof Link) { |
|
|
|
|
$rows[$row_key][$element_key] = $element->getText(); |
|
|
|
|
} |
|
|
|
|
else if (is_array($element)) { |
|
|
|
|
$rows[$row_key][$element_key] = implode('|', $element); |
|
|
|
|
else { |
|
|
|
|
if (is_array($element)) { |
|
|
|
|
$rows[$row_key][$element_key] = implode('|', $element); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return $rows; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Generates and returns a CSV download of the metadata profile. |
|
|
|
|
* |
|
|
|
|
* Writes a temporary CSV file and serves it using Drupal's |
|
|
|
|
* file download controller. |
|
|
|
|
* |
|
|
|
|
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse |
|
|
|
|
* The file download response. |
|
|
|
|
*/ |
|
|
|
|
public function download() { |
|
|
|
|
$contentType = $this->entityBundle; |
|
|
|
|
$entityKey = $this->entityTypeBundleOf; |
|
|
|
|
@ -714,8 +876,7 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
return $this->fileDownloadController->download($request, 'temporary'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function formatFacets(array $field_profile) |
|
|
|
|
{ |
|
|
|
|
private function formatFacets(array $field_profile) { |
|
|
|
|
if (!$field_profile['search_api']['has_facet']) { |
|
|
|
|
return []; |
|
|
|
|
} |
|
|
|
|
@ -738,7 +899,6 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
$build['#rows'][] = $this->formatFacet($facet); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
if (count($build['#rows']) == 0) { |
|
|
|
|
return []; |
|
|
|
|
@ -748,8 +908,7 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function formatFacet($facet) |
|
|
|
|
{ |
|
|
|
|
private function formatFacet($facet) { |
|
|
|
|
return [ |
|
|
|
|
'data' => [ |
|
|
|
|
$facet['field_identifier'], |
|
|
|
|
@ -758,49 +917,95 @@ class MetadataProfileController extends ControllerBase {
|
|
|
|
|
$facet['facet_source'], |
|
|
|
|
$facet['url_alias'], |
|
|
|
|
$facet['block_visible'], |
|
|
|
|
] |
|
|
|
|
], |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function addWeights(array $metadata_profile) |
|
|
|
|
{ |
|
|
|
|
private function addWeights(array $metadata_profile) { |
|
|
|
|
if ($this->entityTypeBundleOf == 'node') { |
|
|
|
|
$node = \Drupal\node\Entity\Node::create(['type' => $this->entityBundle]); |
|
|
|
|
$form = \Drupal::service('entity.form_builder')->getForm($node); |
|
|
|
|
foreach($metadata_profile as $field_name => $field_profile) { |
|
|
|
|
foreach ($metadata_profile as $field_name => $field_profile) { |
|
|
|
|
$metadata_profile[$field_name]['weight'] = $this->getWeight($field_name, $form); |
|
|
|
|
} |
|
|
|
|
$weights = array_column($metadata_profile, 'weight'); |
|
|
|
|
|
|
|
|
|
array_multisort($weights, SORT_ASC, $metadata_profile); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $metadata_profile; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function combine_weights($parent_weight, $local_weight) |
|
|
|
|
{ |
|
|
|
|
$parent_int = (string)floor($parent_weight); |
|
|
|
|
$parent_fraction = (string)($parent_weight - $parent_int); |
|
|
|
|
private function combineWeights($parent_weight, $local_weight) { |
|
|
|
|
$parent_int = (string) floor($parent_weight); |
|
|
|
|
$parent_fraction = (string) ($parent_weight - $parent_int); |
|
|
|
|
$parent_fraction = str_replace('0.', '', $parent_fraction); |
|
|
|
|
$local_int = (string)floor($local_weight); |
|
|
|
|
$local_fraction = (string)($local_weight - $local_int); |
|
|
|
|
$local_int = (string) floor($local_weight); |
|
|
|
|
$local_fraction = (string) ($local_weight - $local_int); |
|
|
|
|
$combined_weight = $parent_int; |
|
|
|
|
$combined_weight .= '.'; |
|
|
|
|
if ($parent_fraction) { |
|
|
|
|
# pad so its length is a multiple of 2 |
|
|
|
|
$length = mb_strlen($parent_fraction); |
|
|
|
|
if (fmod($length, 2) != 0){ |
|
|
|
|
if (fmod($length, 2) != 0) { |
|
|
|
|
$parent_fraction .= '0'; |
|
|
|
|
} |
|
|
|
|
$combined_weight .= $parent_fraction; |
|
|
|
|
} |
|
|
|
|
$combined_weight .= str_pad($local_int, 2, '0', STR_PAD_LEFT); |
|
|
|
|
if ($local_fraction) { |
|
|
|
|
$a=2; |
|
|
|
|
$a = 2; |
|
|
|
|
} |
|
|
|
|
return (float)$combined_weight; |
|
|
|
|
return (float) $combined_weight; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Gets usage count for a field. |
|
|
|
|
* |
|
|
|
|
* For configurable fields, counts rows in the field table. |
|
|
|
|
* For base fields, counts nodes of the current bundle. |
|
|
|
|
* |
|
|
|
|
* @param string $field_name |
|
|
|
|
* The field machine name. |
|
|
|
|
* |
|
|
|
|
* @return int |
|
|
|
|
* Number of usages. |
|
|
|
|
*/ |
|
|
|
|
private function getUsageCount($field_name) { |
|
|
|
|
if (str_starts_with($field_name, 'field_')) { |
|
|
|
|
$connection = $this->database; |
|
|
|
|
$count = $connection->select("node__{$field_name}", 'f') |
|
|
|
|
->countQuery() |
|
|
|
|
->execute() |
|
|
|
|
->fetchField(); |
|
|
|
|
return $count; |
|
|
|
|
} |
|
|
|
|
return $this->entityTypeManagerService |
|
|
|
|
->getStorage('node') |
|
|
|
|
->getQuery() |
|
|
|
|
->accessCheck(FALSE) |
|
|
|
|
->condition('type', $this->entityBundle) |
|
|
|
|
->count() |
|
|
|
|
->execute(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Returns a render array representing a yes/no icon. |
|
|
|
|
* |
|
|
|
|
* @param bool $value |
|
|
|
|
* TRUE for yes, FALSE for no. |
|
|
|
|
* |
|
|
|
|
* @return array |
|
|
|
|
* Render array containing markup for the icon. |
|
|
|
|
*/ |
|
|
|
|
protected function yesNoIcon(bool $value): array { |
|
|
|
|
return [ |
|
|
|
|
'data' => [ |
|
|
|
|
'#markup' => $value |
|
|
|
|
? '<span class="yes-icon" title="Yes">✔</span>' |
|
|
|
|
: '<span class="no-icon" title="No">✖</span>', |
|
|
|
|
], |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|