eav_field-2.x-dev/src/EavAttributeStorage.php
src/EavAttributeStorage.php
<?php
namespace Drupal\eav_field;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\eav_field\Entity\EavAttributeInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\FieldConfigInterface;
use Drupal\taxonomy\TermStorageInterface;
class EavAttributeStorage extends SqlContentEntityStorage {
/**
* Load attributes by properties.
*
* @return EavAttributeInterface[]
*/
public function loadByProperties(array $values = [], $query_alter_callback = NULL): array {
// @see \Drupal\Core\Entity\EntityStorageBase::buildPropertyQuery()
$entity_query = $this->getQuery();
$entity_query->accessCheck(FALSE);
$entity_query->sort('weight');
$this->buildPropertyQuery($entity_query, $values);
if (is_callable($query_alter_callback)) {
$query_alter_callback($entity_query);
}
$result = $entity_query->execute();
return $result ? $this->loadMultiple($result) : [];
}
/**
* Load attributes by category.
*
* @param integer|array|NULL $category Category id, array of ids or NULL for load global attributes.
* @param boolean $including_parents Set TRUE if need including parents categories.
*
* @return EavAttributeInterface[]
*/
public function loadByCategory(int|array|null $category, bool $including_parents = TRUE): array {
if ($category) {
if (!is_array($category)) {
$category = [$category];
}
if ($including_parents) {
$term_storage = $this->entityTypeManager->getStorage('taxonomy_term'); /** @var TermStorageInterface $term_storage */
foreach ($category as $category_id) {
if ($category_all_parents = $term_storage->loadAllParents($category_id)) {
$category = array_merge($category, array_keys($category_all_parents));
}
}
$category = array_unique($category);
}
return $this->loadByProperties(['category' => $category]);
}
$category_field_definition = $this->getCategoryFieldDefinition();
return $this->loadByProperties([], function (QueryInterface $entity_query) use ($category_field_definition) {
if ($category_field_definition) {
$entity_query->notExists('category');
}
});
}
/**
* Load attributes by host entity category.
*
* @return EavAttributeInterface[]
*/
public function loadByHostEntityCategory(FieldableEntityInterface $host_entity, bool $load_global = TRUE): array {
$attributes = [];
// Load global attributes (without categories)
if ($load_global) {
$attributes = $this->loadByCategory(NULL);
}
// Load attributes with certain category (including parents categories)
if ($host_entity_categories = $this->getHostEntityCategories($host_entity)) {
$attributes += $this->loadByCategory($host_entity_categories);
}
return $attributes;
}
/**
* Return host entity categories.
*/
public function getHostEntityCategories(FieldableEntityInterface $host_entity): ?array {
if ($host_entity_category_field = $this->getHostEntityCategoryField($host_entity)) {
$host_entity_categories = [];
foreach ($host_entity->get($host_entity_category_field->getName()) as $item) {
$host_entity_categories[] = $item->target_id;
}
return $host_entity_categories;
}
return NULL;
}
/**
* Return host entity category field definition.
*/
public function getHostEntityCategoryField(FieldableEntityInterface $host_entity): ?FieldDefinitionInterface {
if (
($attribute_category_field_target_info = $this->getCategoryFieldTargetInfo()) &&
$attribute_category_field_target_info['target_bundles']
) {
$attribute_category_target_bundle = key($attribute_category_field_target_info['target_bundles']);
foreach ($host_entity->getFieldDefinitions() as $host_entity_field) {
if (
$host_entity_field->getType() == 'entity_reference' &&
$host_entity_field->getFieldStorageDefinition()->getSetting('target_type') == $attribute_category_field_target_info['target_type'] &&
isset($host_entity_field->getSetting('handler_settings')['target_bundles'][$attribute_category_target_bundle])
) {
return $host_entity_field;
}
}
}
return NULL;
}
/**
* Return category field definition.
*/
public function getCategoryFieldDefinition(): ?FieldConfigInterface {
return FieldConfig::loadByName('eav_attribute', 'eav_attribute', 'category');
}
/**
* Return category field target info.
*/
public function getCategoryFieldTargetInfo(): ?array {
if ($attribute_category_field = $this->getCategoryFieldDefinition()) {
$attribute_category_field_storage = $attribute_category_field->getFieldStorageDefinition();
$attribute_category_field_handler_settings = $attribute_category_field->getSetting('handler_settings');
return [
'target_type' => $attribute_category_field_storage->getSetting('target_type'),
'target_bundles' => $attribute_category_field_handler_settings['target_bundles'] ?? [],
];
}
return NULL;
}
}
