1: <?php
2: /*
3: * Copyright (c) 2015 @trashtoy
4: * https://github.com/trashtoy/
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a copy of
7: * this software and associated documentation files (the "Software"), to deal in
8: * the Software without restriction, including without limitation the rights to use,
9: * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10: * Software, and to permit persons to whom the Software is furnished to do so,
11: * subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in all
14: * copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18: * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19: * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20: * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21: * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22: */
23: /**
24: * PHP class file.
25: * @auhtor trashtoy
26: * @since 2.2.0
27: */
28: namespace Peach\Http\Header;
29:
30: use Peach\Http\SingleHeaderField;
31: use Peach\Http\Util;
32:
33: /**
34: * Accept, Accept-Language, Accept-Encoding など, quality value を値に持つヘッダーを表現するクラスです.
35: */
36: class QualityValues implements SingleHeaderField
37: {
38: /**
39: * ヘッダー名です.
40: *
41: * @var string
42: */
43: private $name;
44:
45: /**
46: * このヘッダーに含まれる quality value の一覧です.
47: *
48: * @var array
49: */
50: private $qvalueList;
51:
52: /**
53: * 指定されたヘッダー名および quality value のリストを持つ QualityValues インスタンスを構築します.
54: *
55: * 第 2 引数には以下のようなフォーマットの配列を指定してください.
56: * <code>
57: * array("ja" => 1.0, "en-US" => 0.9, "en-GB" => 0.8, "en" => 0.7)
58: * </code>
59: *
60: * @param type $name
61: * @param array $qvalueList
62: */
63: public function __construct($name, array $qvalueList)
64: {
65: Util::validateHeaderName($name);
66: foreach ($qvalueList as $key => $value) {
67: $this->validateQvalue($key, $value);
68: }
69: arsort($qvalueList);
70: $this->name = $name;
71: $this->qvalueList = $qvalueList;
72: }
73:
74: /**
75: * それぞれの qvalue の値が 0 以上 1 以下の小数となっていることを確認します.
76: *
77: * @param string $key
78: * @param string $value
79: * @throws \InvalidArgumentException
80: */
81: private function validateQvalue($key, $value)
82: {
83: if (!preg_match("/\\A[a-zA-Z0-9_\\-\\/\\+\\*]+\\z/", $key)) {
84: throw new \InvalidArgumentException("Invalid qvalue name: '{$key}'");
85: }
86: if (!is_numeric($value)) {
87: throw new \InvalidArgumentException("Each qvalue must be a real number");
88: }
89: if ($value < 0 || 1.0 < $value) {
90: throw new \InvalidArgumentException("Each qvalue must be in the range 0 through 1");
91: }
92: }
93:
94: /**
95: * このヘッダーに含まれる quality value の一覧を "," で連結した文字列で出力します.
96: * 各 quality value について, その値が 1.0 に等しい場合はキーのみ,
97: * 1.0 未満の場合は "key;q=value" 形式で書式化されます.
98: *
99: * @return string
100: */
101: public function format()
102: {
103: $callback = function ($key, $value) {
104: return $value === 1.0 ? $key : "{$key};q={$value}";
105: };
106: $qvalueList = $this->qvalueList;
107: return implode(",", array_map($callback, array_keys($qvalueList), array_values($qvalueList)));
108: }
109:
110: /**
111: * このヘッダーの名前を返します.
112: *
113: * @return string
114: */
115: public function getName()
116: {
117: return $this->name;
118: }
119:
120: /**
121: * このヘッダーに含まれる quality value の一覧を配列で返します.
122: *
123: * @return array
124: */
125: public function getValue()
126: {
127: return $this->qvalueList;
128: }
129: }
130: