Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is part of the Symfony package.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Symfony\Component\HttpFoundation;
|
Chris@0
|
13
|
Chris@0
|
14 /**
|
Chris@0
|
15 * Represents an Accept-* header.
|
Chris@0
|
16 *
|
Chris@0
|
17 * An accept header is compound with a list of items,
|
Chris@0
|
18 * sorted by descending quality.
|
Chris@0
|
19 *
|
Chris@0
|
20 * @author Jean-François Simon <contact@jfsimon.fr>
|
Chris@0
|
21 */
|
Chris@0
|
22 class AcceptHeader
|
Chris@0
|
23 {
|
Chris@0
|
24 /**
|
Chris@0
|
25 * @var AcceptHeaderItem[]
|
Chris@0
|
26 */
|
Chris@17
|
27 private $items = [];
|
Chris@0
|
28
|
Chris@0
|
29 /**
|
Chris@0
|
30 * @var bool
|
Chris@0
|
31 */
|
Chris@0
|
32 private $sorted = true;
|
Chris@0
|
33
|
Chris@0
|
34 /**
|
Chris@0
|
35 * @param AcceptHeaderItem[] $items
|
Chris@0
|
36 */
|
Chris@0
|
37 public function __construct(array $items)
|
Chris@0
|
38 {
|
Chris@0
|
39 foreach ($items as $item) {
|
Chris@0
|
40 $this->add($item);
|
Chris@0
|
41 }
|
Chris@0
|
42 }
|
Chris@0
|
43
|
Chris@0
|
44 /**
|
Chris@0
|
45 * Builds an AcceptHeader instance from a string.
|
Chris@0
|
46 *
|
Chris@0
|
47 * @param string $headerValue
|
Chris@0
|
48 *
|
Chris@0
|
49 * @return self
|
Chris@0
|
50 */
|
Chris@0
|
51 public static function fromString($headerValue)
|
Chris@0
|
52 {
|
Chris@0
|
53 $index = 0;
|
Chris@0
|
54
|
Chris@0
|
55 return new self(array_map(function ($itemValue) use (&$index) {
|
Chris@0
|
56 $item = AcceptHeaderItem::fromString($itemValue);
|
Chris@0
|
57 $item->setIndex($index++);
|
Chris@0
|
58
|
Chris@0
|
59 return $item;
|
Chris@0
|
60 }, preg_split('/\s*(?:,*("[^"]+"),*|,*(\'[^\']+\'),*|,+)\s*/', $headerValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE)));
|
Chris@0
|
61 }
|
Chris@0
|
62
|
Chris@0
|
63 /**
|
Chris@0
|
64 * Returns header value's string representation.
|
Chris@0
|
65 *
|
Chris@0
|
66 * @return string
|
Chris@0
|
67 */
|
Chris@0
|
68 public function __toString()
|
Chris@0
|
69 {
|
Chris@0
|
70 return implode(',', $this->items);
|
Chris@0
|
71 }
|
Chris@0
|
72
|
Chris@0
|
73 /**
|
Chris@0
|
74 * Tests if header has given value.
|
Chris@0
|
75 *
|
Chris@0
|
76 * @param string $value
|
Chris@0
|
77 *
|
Chris@0
|
78 * @return bool
|
Chris@0
|
79 */
|
Chris@0
|
80 public function has($value)
|
Chris@0
|
81 {
|
Chris@0
|
82 return isset($this->items[$value]);
|
Chris@0
|
83 }
|
Chris@0
|
84
|
Chris@0
|
85 /**
|
Chris@0
|
86 * Returns given value's item, if exists.
|
Chris@0
|
87 *
|
Chris@0
|
88 * @param string $value
|
Chris@0
|
89 *
|
Chris@0
|
90 * @return AcceptHeaderItem|null
|
Chris@0
|
91 */
|
Chris@0
|
92 public function get($value)
|
Chris@0
|
93 {
|
Chris@0
|
94 return isset($this->items[$value]) ? $this->items[$value] : null;
|
Chris@0
|
95 }
|
Chris@0
|
96
|
Chris@0
|
97 /**
|
Chris@0
|
98 * Adds an item.
|
Chris@0
|
99 *
|
Chris@0
|
100 * @return $this
|
Chris@0
|
101 */
|
Chris@0
|
102 public function add(AcceptHeaderItem $item)
|
Chris@0
|
103 {
|
Chris@0
|
104 $this->items[$item->getValue()] = $item;
|
Chris@0
|
105 $this->sorted = false;
|
Chris@0
|
106
|
Chris@0
|
107 return $this;
|
Chris@0
|
108 }
|
Chris@0
|
109
|
Chris@0
|
110 /**
|
Chris@0
|
111 * Returns all items.
|
Chris@0
|
112 *
|
Chris@0
|
113 * @return AcceptHeaderItem[]
|
Chris@0
|
114 */
|
Chris@0
|
115 public function all()
|
Chris@0
|
116 {
|
Chris@0
|
117 $this->sort();
|
Chris@0
|
118
|
Chris@0
|
119 return $this->items;
|
Chris@0
|
120 }
|
Chris@0
|
121
|
Chris@0
|
122 /**
|
Chris@0
|
123 * Filters items on their value using given regex.
|
Chris@0
|
124 *
|
Chris@0
|
125 * @param string $pattern
|
Chris@0
|
126 *
|
Chris@0
|
127 * @return self
|
Chris@0
|
128 */
|
Chris@0
|
129 public function filter($pattern)
|
Chris@0
|
130 {
|
Chris@0
|
131 return new self(array_filter($this->items, function (AcceptHeaderItem $item) use ($pattern) {
|
Chris@0
|
132 return preg_match($pattern, $item->getValue());
|
Chris@0
|
133 }));
|
Chris@0
|
134 }
|
Chris@0
|
135
|
Chris@0
|
136 /**
|
Chris@0
|
137 * Returns first item.
|
Chris@0
|
138 *
|
Chris@0
|
139 * @return AcceptHeaderItem|null
|
Chris@0
|
140 */
|
Chris@0
|
141 public function first()
|
Chris@0
|
142 {
|
Chris@0
|
143 $this->sort();
|
Chris@0
|
144
|
Chris@0
|
145 return !empty($this->items) ? reset($this->items) : null;
|
Chris@0
|
146 }
|
Chris@0
|
147
|
Chris@0
|
148 /**
|
Chris@0
|
149 * Sorts items by descending quality.
|
Chris@0
|
150 */
|
Chris@0
|
151 private function sort()
|
Chris@0
|
152 {
|
Chris@0
|
153 if (!$this->sorted) {
|
Chris@14
|
154 uasort($this->items, function (AcceptHeaderItem $a, AcceptHeaderItem $b) {
|
Chris@0
|
155 $qA = $a->getQuality();
|
Chris@0
|
156 $qB = $b->getQuality();
|
Chris@0
|
157
|
Chris@0
|
158 if ($qA === $qB) {
|
Chris@0
|
159 return $a->getIndex() > $b->getIndex() ? 1 : -1;
|
Chris@0
|
160 }
|
Chris@0
|
161
|
Chris@0
|
162 return $qA > $qB ? -1 : 1;
|
Chris@0
|
163 });
|
Chris@0
|
164
|
Chris@0
|
165 $this->sorted = true;
|
Chris@0
|
166 }
|
Chris@0
|
167 }
|
Chris@0
|
168 }
|