public function EntityHierarchy::getTree in Entity Reference Hierarchy 3.x
Same name and namespace in other branches
- 8.2 modules/entity_hierarchy_workbench_access/src/Plugin/AccessControlHierarchy/EntityHierarchy.php \Drupal\entity_hierarchy_workbench_access\Plugin\AccessControlHierarchy\EntityHierarchy::getTree()
File
- modules/
entity_hierarchy_workbench_access/ src/ Plugin/ AccessControlHierarchy/ EntityHierarchy.php, line 131
Class
- EntityHierarchy
- Defines a hierarchy based on an entity hierarchy field.
Namespace
Drupal\entity_hierarchy_workbench_access\Plugin\AccessControlHierarchyCode
public function getTree() {
if (!isset($this->tree)) {
if ($data = $this->cacheBackend
->get(self::CACHE_ID)) {
$this->tree = $data->data;
return $this->tree;
}
$entity_type_id = $this->pluginDefinition['entity'];
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
$field_name = $this->pluginDefinition['field_name'];
/** @var \PNX\NestedSet\Storage\DbalNestedSet $tree_storage */
$tree_storage = $this->nestedSetStorageFactory
->get($field_name, $entity_type_id);
$entityStorage = $this->entityTypeManager
->getStorage($entity_type_id);
$query = $entityStorage
->getQuery();
$tree = [];
$or = $query
->orConditionGroup();
$boolean_fields = $this->configuration['boolean_fields'];
foreach ($boolean_fields as $boolean_field) {
$or
->condition($boolean_field, 1);
$tree[$boolean_field] = [];
}
if ($boolean_fields) {
$query
->condition($or);
}
$valid_ids = $query
->execute();
if (!$valid_ids) {
return $tree;
}
$aggregate = $entityStorage
->getAggregateQuery();
$aggregate
->groupBy($entity_type
->getKey('label'))
->groupBy($entity_type
->getKey('id'));
foreach ($boolean_fields as $boolean_field) {
$aggregate
->groupBy($boolean_field);
}
$aggregate
->condition($entity_type
->getKey('id'), $valid_ids, 'IN');
$details = $aggregate
->execute();
$boolean_parents = array_combine(array_column($details, $entity_type
->getKey('id')), array_map(function ($item) use ($entity_type) {
// Remove the label/id fields.
unset($item[$entity_type
->getKey('label')], $item[$entity_type
->getKey('id')]);
// Return just the boolean fields that were checked.
return array_keys(array_filter($item));
}, $details));
$entities = $entityStorage
->loadMultiple($valid_ids);
$tags = $entityStorage
->getEntityType()
->getListCacheTags();
foreach ($entities as $id => $entity) {
/** @var \PNX\NestedSet\Node $node */
$key = $this->keyFactory
->fromEntity($entity);
$node = $tree_storage
->getNode($key);
if (!$node) {
continue;
}
$tags = array_merge($tags, $entities[$id]
->getCacheTags());
foreach ($boolean_parents[$id] as $parent) {
$cid = sprintf('%s:%s', self::CACHE_ID, $id);
if ($entry = $this->cacheBackend
->get($cid)) {
$tree[$parent][$id] = $entry->data;
// Cache hit.
continue;
}
$entry_tags = [];
$entry = [
'label' => $this
->generateEntityLabelWithAncestry($entity, $tree_storage, $entity_type_id, $entry_tags),
'depth' => $node
->getDepth(),
'parents' => [],
'weight' => $node
->getLeft(),
'description' => '',
];
$tree[$parent][$id] = $entry;
$this->cacheBackend
->set($cid, $entry, Cache::PERMANENT, $entry_tags);
$tags = array_merge($tags, $entry_tags);
}
}
foreach (array_keys($tree) as $parent) {
uasort($tree[$parent], function (array $a, array $b) {
// @todo Replace this with null coalesce and spaceship operator when
// we only support PHP 7.0 or greater.
$a_weight = 0;
$b_weight = 0;
if (isset($a['weight'])) {
$a_weight = $a['weight'];
}
if (isset($b['weight'])) {
$b_weight = $b['weight'];
}
if ($a_weight < $b_weight) {
return -1;
}
if ($a_weight > $b_weight) {
return 1;
}
return 0;
});
}
$this->tree = $tree;
$this->cacheBackend
->set(self::CACHE_ID, $tree, Cache::PERMANENT, array_unique($tags));
}
return $this->tree;
}