1<?php 2 3namespace ComboStrap; 4 5/** 6 * A manager to return an unique id for a node 7 * 8 * Example: if you create multiple {@link PageExplorerTag} 9 * you may have several tag for the same page/namespace 10 * but the node id should be unique as it's used for the collapsing 11 */ 12class IdManager 13{ 14 15 16 const CANONICAL = "id-manager"; 17 18 /** 19 * @var array 20 */ 21 private array $lastIdByScope = []; 22 private ExecutionContext $executionContext; 23 24 /** 25 * @param ExecutionContext $executionContext 26 */ 27 public function __construct(ExecutionContext $executionContext) 28 { 29 $this->executionContext = $executionContext; 30 } 31 32 /** 33 * @return IdManager 34 * @deprecated use {@link ExecutionContext::getIdManager()} instead 35 * via {@link ExecutionContext::getExecutingMarkupHandler()} 36 */ 37 static function getOrCreate(): IdManager 38 { 39 40 return ExecutionContext::getActualOrCreateFromEnv()->getIdManager(); 41 42 43 } 44 45 46 public function generateNewHtmlIdForComponent(string $componentId, Path $executingPath = null): string 47 { 48 49 if ($executingPath === null) { 50 51 try { 52 $executingPath = $this->executionContext 53 ->getExecutingMarkupHandler() 54 ->getExecutingPathOrNull(); 55 } catch (ExceptionNotFound $e) { 56 // ok, dynamic, markup string run ? 57 } 58 59 } 60 61 $idScope = $componentId; 62 if ($executingPath !== null) { 63 try { 64 $slotName = $executingPath->getLastNameWithoutExtension(); 65 $idScope = "$idScope-$slotName"; 66 } catch (ExceptionNotFound $e) { 67 // no name (ie root) 68 } 69 } 70 $lastId = self::generateAndGetNewSequenceValueForScope($idScope); 71 72 return Html::toHtmlId("$idScope-$lastId"); 73 } 74 75 private function generateAndGetNewSequenceValueForScope(string $scope) 76 { 77 78 $lastId = $this->lastIdByScope[$scope] ?? null; 79 if ($lastId === null) { 80 $lastId = 1; 81 } else { 82 $lastId = $lastId + 1; 83 } 84 $this->lastIdByScope[$scope] = $lastId; 85 return $lastId; 86 87 } 88 89} 90