Completed
Push — master ( 483eda...cb59ac )
by Дмитрий
03:04
created

Util::splitHeader()   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 13
rs 8.8571
cc 6
eloc 8
nc 3
nop 2
1
<?php
2
/**
3
 * SocialConnect project
4
 * @author: Patsura Dmitry https://github.com/ovr <[email protected]>
5
 */
6
7
namespace SocialConnect\OAuth1;
8
9
class Util
10
{
11
    public static function urlencodeRFC3986($input)
12
    {
13
        if (is_array($input)) {
14
            return array_map(array(
15
                __NAMESPACE__ . '\Util',
16
                'urlencodeRFC3986'
17
            ), $input);
18
        } elseif (is_scalar($input)) {
19
            return rawurlencode($input);
20
        } else {
21
            return '';
22
        }
23
    }
24
25
    // This decode function isn't taking into consideration the above
26
    // modifications to the encoding process. However, this method doesn't
27
    // seem to be used anywhere so leaving it as is.
28
    public static function urldecodeRFC3986($string)
29
    {
30
        return urldecode($string);
31
    }
32
33
    /**
34
     * Utility function for turning the Authorization: header into
35
     * parameters, has to do some unescaping
36
     * Can filter out any non-oauth parameters if needed (default behaviour)
37
     * May 28th, 2010 - method updated to tjerk.meesters for a speed improvement.
38
     * see http://code.google.com/p/oauth/issues/detail?id=163
39
     *
40
     * @param $header
41
     * @param bool|true $oauthParameters Allow only oauth parameters
42
     * @return array
43
     */
44
    public static function splitHeader($header, $oauthParameters = true)
45
    {
46
        $params = array();
47
        if (preg_match_all('/(' . ($oauthParameters ? 'oauth_' : '') . '[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches)) {
48
            foreach ($matches[1] as $i => $h) {
49
                $params[$h] = self::urldecodeRFC3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]);
50
            }
51
            if (isset($params['realm'])) {
52
                unset($params['realm']);
53
            }
54
        }
55
        return $params;
56
    }
57
58
    // helper to try to sort out headers for people who aren't running apache
59
    public static function getHeaders()
60
    {
61
        if (function_exists('apache_request_headers')) {
62
            // we need this to get the actual Authorization: header
63
            // because apache tends to tell us it doesn't exist
64
            $headers = apache_request_headers();
65
66
            // sanitize the output of apache_request_headers because
67
            // we always want the keys to be Cased-Like-This and arh()
68
            // returns the headers in the same case as they are in the
69
            // request
70
            $out = array();
71
            foreach ($headers as $key => $value) {
72
                $key       = str_replace(" ", "-", ucwords(strtolower(str_replace("-", " ", $key))));
73
                $out[$key] = $value;
74
            }
75
        } else {
76
            // otherwise we don't have apache and are just going to have to hope
77
            // that $_SERVER actually contains what we need
78
            $out = array();
79
            if (isset($_SERVER['CONTENT_TYPE'])) {
80
                $out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
81
            }
82
            if (isset($_ENV['CONTENT_TYPE'])) {
83
                $out['Content-Type'] = $_ENV['CONTENT_TYPE'];
84
            }
85
86
            foreach ($_SERVER as $key => $value) {
87
                if (substr($key, 0, 5) == "HTTP_") {
88
                    // this is chaos, basically it is just there to capitalize the first
89
                    // letter of every word that is not an initial HTTP and strip HTTP
90
                    // code from przemek
91
                    $key       = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))));
92
                    $out[$key] = $value;
93
                }
94
            }
95
        }
96
        return $out;
97
    }
98
    // This function takes a input like a=b&a=c&d=e and returns the parsed
99
    // parameters like this
100
    // array('a' => array('b','c'), 'd' => 'e')
101
    public static function parseParameters($input)
102
    {
103
        if (!isset($input) || !$input) {
104
            return array();
105
        }
106
107
        $pairs = explode('&', $input);
108
109
        $parsed_parameters = array();
110
        foreach ($pairs as $pair) {
111
            $split     = explode('=', $pair, 2);
112
            $parameter = self::urldecodeRFC3986($split[0]);
113
            $value     = isset($split[1]) ? self::urldecodeRFC3986($split[1]) : '';
114
115
            if (isset($parsed_parameters[$parameter])) {
116
                // We have already recieved parameter(s) with this name, so add to the list
117
                // of parameters with this name
118
119
                if (is_scalar($parsed_parameters[$parameter])) {
120
                    // This is the first duplicate, so transform scalar (string) into an array
121
                    // so we can add the duplicates
122
                    $parsed_parameters[$parameter] = array(
123
                        $parsed_parameters[$parameter]
124
                    );
125
                }
126
127
                $parsed_parameters[$parameter][] = $value;
128
            } else {
129
                $parsed_parameters[$parameter] = $value;
130
            }
131
        }
132
        return $parsed_parameters;
133
    }
134
    public static function buildHttpQuery($params)
135
    {
136
        if (!$params) {
137
            return '';
138
        }
139
140
        // Urlencode both keys and values
141
        $keys   = self::urlencodeRFC3986(array_keys($params));
142
        $values = self::urlencodeRFC3986(array_values($params));
143
        $params = array_combine($keys, $values);
144
145
        // Parameters are sorted by name, using lexicographical byte value ordering.
146
        // Ref: Spec: 9.1.1 (1)
147
        uksort($params, 'strcmp');
148
149
        $pairs = array();
150
        foreach ($params as $parameter => $value) {
151
            if (is_array($value)) {
152
                // If two or more parameters share the same name, they are sorted by their value
153
                // Ref: Spec: 9.1.1 (1)
154
                // June 12th, 2010 - changed to sort because of issue 164 by hidetaka
155
                sort($value, SORT_STRING);
156
                foreach ($value as $duplicate_value) {
157
                    $pairs[] = $parameter . '=' . $duplicate_value;
158
                }
159
            } else {
160
                $pairs[] = $parameter . '=' . $value;
161
            }
162
        }
163
        // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
164
        // Each name-value pair is separated by an '&' character (ASCII code 38)
165
        return implode('&', $pairs);
166
    }
167
}
168