module/Application/src/Hydrator/Api/ItemParentHydrator.php
<?php
namespace Application\Hydrator\Api;
use Application\Model\Item;
use Application\Model\ItemParent;
use ArrayAccess;
use Autowp\User\Model\User;
use Casbin\Enforcer;
use Exception;
use Laminas\Hydrator\Exception\InvalidArgumentException;
use Laminas\ServiceManager\ServiceLocatorInterface;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
use function is_array;
class ItemParentHydrator extends AbstractRestHydrator
{
private int $userId = 0;
private ?string $userRole;
private Item $item;
private ItemParent $itemParent;
private Enforcer $acl;
private User $userModel;
public function __construct(ServiceLocatorInterface $serviceManager)
{
parent::__construct();
$this->itemParent = $serviceManager->get(ItemParent::class);
$this->item = $serviceManager->get(Item::class);
$this->acl = $serviceManager->get(Enforcer::class);
$this->userModel = $serviceManager->get(User::class);
$strategy = new Strategy\Item($serviceManager);
$this->addStrategy('item', $strategy);
$strategy = new Strategy\Item($serviceManager);
$this->addStrategy('parent', $strategy);
$strategy = new Strategy\Item($serviceManager);
$this->addStrategy('duplicate_parent', $strategy);
$strategy = new Strategy\Item($serviceManager);
$this->addStrategy('duplicate_child', $strategy);
}
/**
* @param array|Traversable $options
* @throws InvalidArgumentException
*/
public function setOptions($options): self
{
parent::setOptions($options);
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (! is_array($options)) {
throw new InvalidArgumentException(
'The options parameter must be an array or a Traversable'
);
}
if (isset($options['user_id'])) {
$this->setUserId($options['user_id']);
}
return $this;
}
/**
* @param int|null $userId
*/
public function setUserId($userId = null): self
{
$this->userId = (int) $userId;
/** @var Strategy\Item $strategy */
$strategy = $this->getStrategy('item');
$strategy->setUserId($userId);
/** @var Strategy\Item $strategy */
$strategy = $this->getStrategy('parent');
$strategy->setUserId($userId);
/** @var Strategy\Item $strategy */
$strategy = $this->getStrategy('duplicate_parent');
$strategy->setUserId($userId);
/** @var Strategy\Item $strategy */
$strategy = $this->getStrategy('duplicate_child');
$strategy->setUserId($userId);
return $this;
}
/**
* @param array|ArrayAccess $object
* @throws Exception
*/
public function extract($object): ?array
{
$result = [
'item_id' => (int) $object['item_id'],
'parent_id' => (int) $object['parent_id'],
'type_id' => (int) $object['type'],
'catname' => $object['catname'],
];
$isModer = false;
$role = $this->getUserRole();
if ($role) {
$isModer = $this->acl->enforce($role, 'global', 'moderate');
}
if ($this->filterComposite->filter('item')) {
$item = $this->item->getRow(['id' => $object['item_id']]);
$result['item'] = $item ? $this->extractValue('item', $item) : null;
}
if ($isModer) {
if ($this->filterComposite->filter('parent')) {
$item = $this->item->getRow(['id' => $object['parent_id']]);
$result['parent'] = $item ? $this->extractValue('parent', $item) : null;
}
if ($this->filterComposite->filter('name')) {
$result['name'] = $this->itemParent->getNamePreferLanguage(
$object['parent_id'],
$object['item_id'],
$this->language
);
}
if ($this->filterComposite->filter('duplicate_parent')) {
$duplicateRow = $this->item->getRow([
'exclude_id' => $object['parent_id'],
'child' => [
'id' => $object['item_id'],
'link_type' => ItemParent::TYPE_DEFAULT,
],
'ancestor_or_self' => [
'id' => $object['parent_id'],
'stock_only' => true,
],
]);
$result['duplicate_parent'] = $duplicateRow
? $this->extractValue('duplicate_parent', $duplicateRow) : null;
}
if ($this->filterComposite->filter('duplicate_child')) {
$duplicateRow = $this->item->getRow([
'exclude_id' => $object['item_id'],
'parent' => [
'id' => $object['parent_id'],
'link_type' => $object['type'],
],
'descendant_or_self' => $object['item_id'],
]);
$result['duplicate_child'] = $duplicateRow
? $this->extractValue('duplicate_child', $duplicateRow) : null;
}
}
return $result;
}
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
* @param object $object
* @throws Exception
*/
public function hydrate(array $data, $object): object
{
throw new Exception("Not supported");
}
/**
* @throws Exception
*/
private function getUserRole(): ?string
{
if (! $this->userId) {
return null;
}
if (! isset($this->userRole)) {
$this->userRole = $this->userModel->getUserRole($this->userId);
}
return $this->userRole;
}
}