<?php
namespace Newland\NeosCommon\Aspects;

use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Aop\JoinPointInterface;

/**
 * Aspect that adds node caching to the `NodePrivilegeContext` which is being used when evaluating Policies.
 * This aspect applies code of the following PR to existing non-patched Neos instances:
 * @see https://github.com/neos/neos-development-collection/pull/2302
 *
 * This class can be deleted once the following related Issue in Neos has been resolved
 * (and instances have been updated):
 * @see https://github.com/neos/neos-development-collection/pull/2302
 *
 * @Flow\Aspect()
 */
class CacheNodesForPrivilegeEvaluation
{

    /** @var array<string, NodeInterface> */
    protected static $nodes = [];

    /**
     * phpcs:disable Generic.Files.LineLength.TooLong
     * @Flow\Around("method(Neos\ContentRepository\Security\Authorization\Privilege\Node\NodePrivilegeContext->getNodeByIdentifier())")
     * phpcs:enable
     *
     * @return mixed
     */
    public function getNodeByIdentifier(JoinPointInterface $joinPoint)
    {
        $nodeIdentifier = $joinPoint->getMethodArgument('nodeIdentifier');
        if (array_key_exists($nodeIdentifier, static::$nodes)) {
            return static::$nodes[$nodeIdentifier];
        }

        $node = $joinPoint->getAdviceChain()->proceed($joinPoint);
        if ($node) {
            static::$nodes[$nodeIdentifier] = $node;
        }
        return $node;
    }
}
