xref: /plugin/combo/ComboStrap/IdManager.php (revision be61a7dff863d71b511ec3d76c85eae93b93e8bc)
104fd306cSNickeau<?php
204fd306cSNickeau
304fd306cSNickeaunamespace ComboStrap;
404fd306cSNickeau
504fd306cSNickeau/**
604fd306cSNickeau * A manager to return an unique id for a node
704fd306cSNickeau *
804fd306cSNickeau * Example: if you create multiple {@link PageExplorerTag}
904fd306cSNickeau * you may have several tag for the same page/namespace
1004fd306cSNickeau * but the node id should be unique as it's used for the collapsing
1104fd306cSNickeau */
1204fd306cSNickeauclass IdManager
1304fd306cSNickeau{
1404fd306cSNickeau
1504fd306cSNickeau
1604fd306cSNickeau    const CANONICAL = "id-manager";
1704fd306cSNickeau
1804fd306cSNickeau    /**
1904fd306cSNickeau     * @var array
2004fd306cSNickeau     */
2104fd306cSNickeau    private array $lastIdByScope = [];
2204fd306cSNickeau    private ExecutionContext $executionContext;
2304fd306cSNickeau
2404fd306cSNickeau    /**
2504fd306cSNickeau     * @param ExecutionContext $executionContext
2604fd306cSNickeau     */
2704fd306cSNickeau    public function __construct(ExecutionContext $executionContext)
2804fd306cSNickeau    {
2904fd306cSNickeau        $this->executionContext = $executionContext;
3004fd306cSNickeau    }
3104fd306cSNickeau
3204fd306cSNickeau    /**
3304fd306cSNickeau     * @return IdManager
3404fd306cSNickeau     * @deprecated use {@link ExecutionContext::getIdManager()} instead
3504fd306cSNickeau     * via {@link ExecutionContext::getExecutingMarkupHandler()}
3604fd306cSNickeau     */
3704fd306cSNickeau    static function getOrCreate(): IdManager
3804fd306cSNickeau    {
3904fd306cSNickeau
4004fd306cSNickeau        return ExecutionContext::getActualOrCreateFromEnv()->getIdManager();
4104fd306cSNickeau
4204fd306cSNickeau
4304fd306cSNickeau    }
4404fd306cSNickeau
4504fd306cSNickeau
4604fd306cSNickeau    public function generateNewHtmlIdForComponent(string $componentId, Path $executingPath = null): string
4704fd306cSNickeau    {
4804fd306cSNickeau
4904fd306cSNickeau        if ($executingPath === null) {
5004fd306cSNickeau
5104fd306cSNickeau            try {
5204fd306cSNickeau                $executingPath = $this->executionContext
5304fd306cSNickeau                    ->getExecutingMarkupHandler()
5404fd306cSNickeau                    ->getExecutingPathOrNull();
5504fd306cSNickeau            } catch (ExceptionNotFound $e) {
5604fd306cSNickeau                // ok, dynamic, markup string run ?
5704fd306cSNickeau            }
5804fd306cSNickeau
5904fd306cSNickeau        }
6004fd306cSNickeau
6104fd306cSNickeau        $idScope = $componentId;
6204fd306cSNickeau        if ($executingPath !== null) {
6304fd306cSNickeau            try {
6404fd306cSNickeau                $slotName = $executingPath->getLastNameWithoutExtension();
6504fd306cSNickeau                $idScope = "$idScope-$slotName";
6604fd306cSNickeau            } catch (ExceptionNotFound $e) {
6704fd306cSNickeau                // no name (ie root)
6804fd306cSNickeau            }
6904fd306cSNickeau        }
7004fd306cSNickeau        $lastId = self::generateAndGetNewSequenceValueForScope($idScope);
7104fd306cSNickeau
7204fd306cSNickeau        return Html::toHtmlId("$idScope-$lastId");
7304fd306cSNickeau    }
7404fd306cSNickeau
7504fd306cSNickeau    private function generateAndGetNewSequenceValueForScope(string $scope)
7604fd306cSNickeau    {
7704fd306cSNickeau
78*be61a7dfSgerardnico        $lastId = $this->lastIdByScope[$scope] ?? null;
7904fd306cSNickeau        if ($lastId === null) {
8004fd306cSNickeau            $lastId = 1;
8104fd306cSNickeau        } else {
8204fd306cSNickeau            $lastId = $lastId + 1;
8304fd306cSNickeau        }
8404fd306cSNickeau        $this->lastIdByScope[$scope] = $lastId;
8504fd306cSNickeau        return $lastId;
8604fd306cSNickeau
8704fd306cSNickeau    }
8804fd306cSNickeau
8904fd306cSNickeau}
90