Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\HttpFoundation; Chris@0: Chris@0: /** Chris@0: * Represents an Accept-* header. Chris@0: * Chris@0: * An accept header is compound with a list of items, Chris@0: * sorted by descending quality. Chris@0: * Chris@0: * @author Jean-François Simon Chris@0: */ Chris@0: class AcceptHeader Chris@0: { Chris@0: /** Chris@0: * @var AcceptHeaderItem[] Chris@0: */ Chris@17: private $items = []; Chris@0: Chris@0: /** Chris@0: * @var bool Chris@0: */ Chris@0: private $sorted = true; Chris@0: Chris@0: /** Chris@0: * @param AcceptHeaderItem[] $items Chris@0: */ Chris@0: public function __construct(array $items) Chris@0: { Chris@0: foreach ($items as $item) { Chris@0: $this->add($item); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Builds an AcceptHeader instance from a string. Chris@0: * Chris@0: * @param string $headerValue Chris@0: * Chris@0: * @return self Chris@0: */ Chris@0: public static function fromString($headerValue) Chris@0: { Chris@0: $index = 0; Chris@0: Chris@0: return new self(array_map(function ($itemValue) use (&$index) { Chris@0: $item = AcceptHeaderItem::fromString($itemValue); Chris@0: $item->setIndex($index++); Chris@0: Chris@0: return $item; Chris@0: }, preg_split('/\s*(?:,*("[^"]+"),*|,*(\'[^\']+\'),*|,+)\s*/', $headerValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE))); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns header value's string representation. Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function __toString() Chris@0: { Chris@0: return implode(',', $this->items); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests if header has given value. Chris@0: * Chris@0: * @param string $value Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function has($value) Chris@0: { Chris@0: return isset($this->items[$value]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns given value's item, if exists. Chris@0: * Chris@0: * @param string $value Chris@0: * Chris@0: * @return AcceptHeaderItem|null Chris@0: */ Chris@0: public function get($value) Chris@0: { Chris@0: return isset($this->items[$value]) ? $this->items[$value] : null; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds an item. Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function add(AcceptHeaderItem $item) Chris@0: { Chris@0: $this->items[$item->getValue()] = $item; Chris@0: $this->sorted = false; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns all items. Chris@0: * Chris@0: * @return AcceptHeaderItem[] Chris@0: */ Chris@0: public function all() Chris@0: { Chris@0: $this->sort(); Chris@0: Chris@0: return $this->items; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Filters items on their value using given regex. Chris@0: * Chris@0: * @param string $pattern Chris@0: * Chris@0: * @return self Chris@0: */ Chris@0: public function filter($pattern) Chris@0: { Chris@0: return new self(array_filter($this->items, function (AcceptHeaderItem $item) use ($pattern) { Chris@0: return preg_match($pattern, $item->getValue()); Chris@0: })); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns first item. Chris@0: * Chris@0: * @return AcceptHeaderItem|null Chris@0: */ Chris@0: public function first() Chris@0: { Chris@0: $this->sort(); Chris@0: Chris@0: return !empty($this->items) ? reset($this->items) : null; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sorts items by descending quality. Chris@0: */ Chris@0: private function sort() Chris@0: { Chris@0: if (!$this->sorted) { Chris@14: uasort($this->items, function (AcceptHeaderItem $a, AcceptHeaderItem $b) { Chris@0: $qA = $a->getQuality(); Chris@0: $qB = $b->getQuality(); Chris@0: Chris@0: if ($qA === $qB) { Chris@0: return $a->getIndex() > $b->getIndex() ? 1 : -1; Chris@0: } Chris@0: Chris@0: return $qA > $qB ? -1 : 1; Chris@0: }); Chris@0: Chris@0: $this->sorted = true; Chris@0: } Chris@0: } Chris@0: }