Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

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