bim_gdpr-1.0.0-rc3/src/Hierarchy/Hierarchy.php
src/Hierarchy/Hierarchy.php
<?php
namespace Drupal\bim_gdpr\Hierarchy;
use Drupal\bim_gdpr\BimGdprGroupInterface;
use Drupal\bim_gdpr\BimGdprServiceInterface;
use Drupal\bim_gdpr\Entity\BimGdprGroup;
use Drupal\bim_gdpr\Entity\BimGdprService;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
/**
* Class Hierarchy.
*
* This class is used for organizing heirarhcy items.
*
* @package Drupal\bim_gdpr\Hierarchy
*/
class Hierarchy implements HierarchyInterface {
use StringTranslationTrait;
/**
* List of root Items.
*
* @var \Drupal\Core\Entity\EntityInterface[]
*/
protected $rootList = [];
/**
* List of all items.
*
* @var \Drupal\Core\Entity\EntityInterface[]
*/
protected $itemList = [];
/**
* Raw items.
*
* @var array
*/
protected $rawList;
/**
* Hierarchy constructor.
*
* @param \Drupal\Core\Entity\EntityInterface[] $rawList
* The raw list.
*/
public function __construct(array $rawList = []) {
$this->rawList = $rawList;
$this->rawList = $this->sortRawList($rawList);
$this->checkConsistency();
$this->initHierarchy();
}
/**
* {@inheritdoc}
*/
public function hasGroup(): bool {
return static::rawDataHasGroup($this->rawList);
}
/**
* Return true if raw data has group.
*
* @param array $rawData
* The raw data.
*
* @return bool
* The state.
*/
public static function rawDataHasGroup(array $rawData): bool {
return count(array_filter($rawData, function (array $item) {
return $item['type']['entity_type_id'] === BimGdprGroupInterface::ENTITY_TYPE_ID;
})) > 0;
}
/**
* {@inheritdoc}
*/
public function checkConsistency(): void {
if ($this->hasGroup()
&& $firstItem = reset($this->rawList)) {
if ($firstItem['type']['entity_type_id'] === BimGdprServiceInterface::ENTITY_TYPE_ID) {
/* throw new \Exception('Grouped configuration cannot
start with a service. It has to start with a group.'); */
}
}
}
/**
* {@inheritdoc}
*/
public function getRaw(): array {
return $this->rawList;
}
/**
* Return the raw id.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity.
*
* @return string
* The id.
*/
public static function getEntityRawId(EntityInterface $entity) {
return $entity->getEntityTypeId() . HierarchyInterface::PREFIX . $entity->id();
}
/**
* {@inheritdoc}
*/
public function getRoot(): array {
return $this->rootList;
}
/**
* {@inheritdoc}
*/
public function getChildrenOfItem(EntityInterface $parent): array {
return $parent->_children ?: [];
}
/**
* {@inheritdoc}
*/
public function getWeightOfItem(EntityInterface $item): int {
return $item->_weight;
}
/**
* {@inheritdoc}
*/
public function getParentOfItem(EntityInterface $item) {
return isset($item->_parent) ? $item->_parent : '';
}
/**
* Init the hierarchy items.
*/
protected function initHierarchy() {
$group = NULL;
$weight = 0;
foreach ($this->getRaw() as $prefixedId => $item) {
$id = $this->getIdFromPrefixedId($prefixedId);
switch ($item['type']['entity_type_id']) {
case BimGdprGroupInterface::ENTITY_TYPE_ID:
if ($group = $this->getGroupFromRawData($id, $weight)) {
$this->rootList[] = $group;
}
$this->itemList[] = $group;
break;
case BimGdprServiceInterface::ENTITY_TYPE_ID:
$service = $this->getServiceFromRawData($id, $weight, $group);
if ($group) {
$group->_children[] = $service;
}
else {
$this->rootList[] = $service;
}
$this->itemList[] = $service;
break;
}
}
}
/**
* Return the group from the data.
*
* @param string $id
* The id.
* @param int $weight
* The weight.
*
* @return \Drupal\bim_gdpr\BimGdprGroupInterface|null
* The group.
*/
protected function getGroupFromRawData(string $id, int &$weight) {
if ($group = BimGdprGroup::loadLanguaged($id, \Drupal::languageManager()
->getCurrentLanguage()
->getId())) {
$group->_children = [];
$group->_weight = $weight++;
}
return $group;
}
/**
* Return the service from the data.
*
* @param string $id
* The id.
* @param int $weight
* The weight.
* @param \Drupal\Core\Entity\EntityInterface|null $parent
* The parent entity.
*
* @return \Drupal\bim_gdpr\BimGdprServiceInterface|null
* The service.
*/
protected function getServiceFromRawData(string $id, int &$weight, EntityInterface $parent = NULL) {
if ($service = BimGdprService::loadLanguaged($id, \Drupal::languageManager()
->getCurrentLanguage()
->getId())) {
$service->_weight = $weight++;
if ($parent) {
$service->_parent = $parent;
}
}
return $service;
}
/**
* Return id from prefixed id.
*
* @param string $prefixedId
* THe prefix id.
*
* @return string
* The id.
*/
protected function getIdFromPrefixedId(string $prefixedId) {
$data = explode(HierarchyInterface::PREFIX, $prefixedId);
return end($data);
}
/**
* Sort the raw list.
*
* @param array $rawList
* The raw list.
*
* @return mixed
* The sorted raw list.
*/
protected function sortRawList(array $rawList) {
uasort($rawList, function ($a, $b) {
$a = isset($a['weight']) ? $a['weight'] : 0;
$b = isset($b['weight']) ? $b['weight'] : 0;
if ($a > $b) {
return 1;
}
elseif ($a < $b) {
return -1;
}
return 0;
});
return $rawList;
}
/**
* {@inheritdoc}
*/
public function getJsData(): array {
$data = [];
$group = NULL;
foreach ($this->itemList as $item) {
switch ($item->getEntityTypeId()) {
case BimGdprGroupInterface::ENTITY_TYPE_ID:
if ($item->status()) {
$data['groups'][] = $this->getGroupJsData($item);
}
$group = $item;
break;
case BimGdprServiceInterface::ENTITY_TYPE_ID:
if (!$group || ($group && $group->status())) {
if ($item->status()) {
$data['services'][] = $this->getServiceJsData($item);
}
}
break;
}
}
return $data;
}
/**
* Return group data.
*
* @param \Drupal\bim_gdpr\BimGdprGroupInterface $group
* The group.
*
* @return array
* The group js data.
*/
protected function getGroupJsData(BimGdprGroupInterface $group) {
return [
'id' => $group->id(),
'label' => $this->t($group->label()),
'description' => $this->t($group->get('description')),
'weight' => $this->getWeightOfItem($group),
];
}
/**
* Return service data.
*
* @param \Drupal\bim_gdpr\BimGdprServiceInterface $service
* The service.
*
* @return array
* The service js data.
*/
protected function getServiceJsData(BimGdprServiceInterface $service) {
$data = $service->getData();
$service->getServiceType()->alterSettingsBeforeApply($data);
$parent = $this->getParentOfItem($service);
return [
'id' => $service->id(),
'type' => $service->getServiceTypeId(),
'label' => $this->t($service->label()),
'description' => $this->t($service->get('description')),
'settings' => $data,
'parent' => $parent ? $parent->id() : '',
'weight' => $this->getWeightOfItem($service),
];
}
}
