*/ class ChainTokenExtractor implements \IteratorAggregate, TokenExtractorInterface { private array $map; public function __construct(array $map) { $this->map = $map; } /** * Adds a new token extractor to the map. */ public function addExtractor(TokenExtractorInterface $extractor) { $this->map[] = $extractor; } /** * Removes a token extractor from the map. * * @param \Closure $filter A function taking an extractor as argument, used to find the extractor to remove. * * @return bool True in case of success, false otherwise */ public function removeExtractor(\Closure $filter) { $filtered = array_filter($this->map, $filter); if (!$extractorToUnmap = current($filtered)) { return false; } $key = array_search($extractorToUnmap, $this->map); unset($this->map[$key]); return true; } /** * Clears the token extractor map. */ public function clearMap() { $this->map = []; } /** * Iterates over the token extractors map calling {@see extract()} * until a token is found. * * {@inheritdoc} */ public function extract(Request $request) { foreach ($this->getIterator() as $extractor) { if ($token = $extractor->extract($request)) { return $token; } } return false; } /** * Iterates over the mapped token extractors while generating them. * * @return \Traversable */ #[\ReturnTypeWillChange] public function getIterator() { foreach ($this->map as $extractor) { if ($extractor instanceof TokenExtractorInterface) { yield $extractor; } } } }