Subversion Repositories Applications.framework

Rev

Rev 79 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 79 Rev 80
1
<?php
1
<?php
2
// +-----------------------------------------------------------------------+
2
// +-----------------------------------------------------------------------+
3
// | Copyright (c) 2007-2008, Christian Schmidt, Peytz & Co. A/S           |
3
// | Copyright (c) 2007-2008, Christian Schmidt, Peytz & Co. A/S           |
4
// | All rights reserved.                                                  |
4
// | All rights reserved.                                                  |
5
// |                                                                       |
5
// |                                                                       |
6
// | Redistribution and use in source and binary forms, with or without    |
6
// | Redistribution and use in source and binary forms, with or without    |
7
// | modification, are permitted provided that the following conditions    |
7
// | modification, are permitted provided that the following conditions    |
8
// | are met:                                                              |
8
// | are met:                                                              |
9
// |                                                                       |
9
// |                                                                       |
10
// | o Redistributions of source code must retain the above copyright      |
10
// | o Redistributions of source code must retain the above copyright      |
11
// |   notice, this list of conditions and the following disclaimer.       |
11
// |   notice, this list of conditions and the following disclaimer.       |
12
// | o Redistributions in binary form must reproduce the above copyright   |
12
// | o Redistributions in binary form must reproduce the above copyright   |
13
// |   notice, this list of conditions and the following disclaimer in the |
13
// |   notice, this list of conditions and the following disclaimer in the |
14
// |   documentation and/or other materials provided with the distribution.|
14
// |   documentation and/or other materials provided with the distribution.|
15
// | o The names of the authors may not be used to endorse or promote      |
15
// | o The names of the authors may not be used to endorse or promote      |
16
// |   products derived from this software without specific prior written  |
16
// |   products derived from this software without specific prior written  |
17
// |   permission.                                                         |
17
// |   permission.                                                         |
18
// |                                                                       |
18
// |                                                                       |
19
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
19
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
20
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
20
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
21
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
22
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
22
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
23
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
24
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
25
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
27
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
28
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
29
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
30
// |                                                                       |
30
// |                                                                       |
31
// +-----------------------------------------------------------------------+
31
// +-----------------------------------------------------------------------+
32
// | Author: Christian Schmidt <schmidt at php dot net>                    |
32
// | Author: Christian Schmidt <schmidt at php dot net>                    |
33
// +-----------------------------------------------------------------------+
33
// +-----------------------------------------------------------------------+
34
//
34
//
35
// $Id: Net_URL2.php 34 2009-04-09 07:34:39Z aurelien $
35
// $Id: Net_URL2.php 80 2009-08-27 07:30:42Z jpm $
36
//
36
//
37
// Net_URL2 Class (PHP5 Only)
37
// Net_URL2 Class (PHP5 Only)
38
 
38
 
39
// This code is released under the BSD License - http://www.opensource.org/licenses/bsd-license.php
39
// This code is released under the BSD License - http://www.opensource.org/licenses/bsd-license.php
40
/**
40
/**
41
 * @license BSD License
41
 * @license BSD License
42
 */
42
 */
43
class Net_URL2
43
class Net_URL2
44
{
44
{
45
    /**
45
    /**
46
     * Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default
46
     * Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default
47
     * is true.
47
     * is true.
48
     */
48
     */
49
    const OPTION_STRICT           = 'strict';
49
    const OPTION_STRICT           = 'strict';
50
 
50
 
51
    /**
51
    /**
52
     * Represent arrays in query using PHP's [] notation. Default is true.
52
     * Represent arrays in query using PHP's [] notation. Default is true.
53
     */
53
     */
54
    const OPTION_USE_BRACKETS     = 'use_brackets';
54
    const OPTION_USE_BRACKETS     = 'use_brackets';
55
 
55
 
56
    /**
56
    /**
57
     * URL-encode query variable keys. Default is true.
57
     * URL-encode query variable keys. Default is true.
58
     */
58
     */
59
    const OPTION_ENCODE_KEYS      = 'encode_keys';
59
    const OPTION_ENCODE_KEYS      = 'encode_keys';
60
 
60
 
61
    /**
61
    /**
62
     * Query variable separators when parsing the query string. Every character
62
     * Query variable separators when parsing the query string. Every character
63
     * is considered a separator. Default is specified by the
63
     * is considered a separator. Default is specified by the
64
     * arg_separator.input php.ini setting (this defaults to "&").
64
     * arg_separator.input php.ini setting (this defaults to "&").
65
     */
65
     */
66
    const OPTION_SEPARATOR_INPUT  = 'input_separator';
66
    const OPTION_SEPARATOR_INPUT  = 'input_separator';
67
 
67
 
68
    /**
68
    /**
69
     * Query variable separator used when generating the query string. Default
69
     * Query variable separator used when generating the query string. Default
70
     * is specified by the arg_separator.output php.ini setting (this defaults
70
     * is specified by the arg_separator.output php.ini setting (this defaults
71
     * to "&").
71
     * to "&").
72
     */
72
     */
73
    const OPTION_SEPARATOR_OUTPUT = 'output_separator';
73
    const OPTION_SEPARATOR_OUTPUT = 'output_separator';
74
 
74
 
75
    /**
75
    /**
76
     * Default options corresponds to how PHP handles $_GET.
76
     * Default options corresponds to how PHP handles $_GET.
77
     */
77
     */
78
    private $options = array(
78
    private $options = array(
79
        self::OPTION_STRICT           => true,
79
        self::OPTION_STRICT           => true,
80
        self::OPTION_USE_BRACKETS     => true,
80
        self::OPTION_USE_BRACKETS     => true,
81
        self::OPTION_ENCODE_KEYS      => true,
81
        self::OPTION_ENCODE_KEYS      => true,
82
        self::OPTION_SEPARATOR_INPUT  => 'x&',
82
        self::OPTION_SEPARATOR_INPUT  => 'x&',
83
        self::OPTION_SEPARATOR_OUTPUT => 'x&',
83
        self::OPTION_SEPARATOR_OUTPUT => 'x&',
84
        );
84
        );
85
 
85
 
86
    /**
86
    /**
87
     * @var  string|bool
87
     * @var  string|bool
88
     */
88
     */
89
    private $scheme = false;
89
    private $scheme = false;
90
 
90
 
91
    /**
91
    /**
92
     * @var  string|bool
92
     * @var  string|bool
93
     */
93
     */
94
    private $userinfo = false;
94
    private $userinfo = false;
95
 
95
 
96
    /**
96
    /**
97
     * @var  string|bool
97
     * @var  string|bool
98
     */
98
     */
99
    private $host = false;
99
    private $host = false;
100
 
100
 
101
    /**
101
    /**
102
     * @var  int|bool
102
     * @var  int|bool
103
     */
103
     */
104
    private $port = false;
104
    private $port = false;
105
 
105
 
106
    /**
106
    /**
107
     * @var  string
107
     * @var  string
108
     */
108
     */
109
    private $path = '';
109
    private $path = '';
110
 
110
 
111
    /**
111
    /**
112
     * @var  string|bool
112
     * @var  string|bool
113
     */
113
     */
114
    private $query = false;
114
    private $query = false;
115
 
115
 
116
    /**
116
    /**
117
     * @var  string|bool
117
     * @var  string|bool
118
     */
118
     */
119
    private $fragment = false;
119
    private $fragment = false;
120
 
120
 
121
    /**
121
    /**
122
     * @param string $url     an absolute or relative URL
122
     * @param string $url     an absolute or relative URL
123
     * @param array  $options
123
     * @param array  $options
124
     */
124
     */
125
    public function __construct($url, $options = null)
125
    public function __construct($url, $options = null)
126
    {
126
    {
127
        $this->setOption(self::OPTION_SEPARATOR_INPUT,
127
        $this->setOption(self::OPTION_SEPARATOR_INPUT,
128
                         ini_get('arg_separator.input'));
128
                         ini_get('arg_separator.input'));
129
        $this->setOption(self::OPTION_SEPARATOR_OUTPUT,
129
        $this->setOption(self::OPTION_SEPARATOR_OUTPUT,
130
                         ini_get('arg_separator.output'));
130
                         ini_get('arg_separator.output'));
131
        if (is_array($options)) {
131
        if (is_array($options)) {
132
            foreach ($options as $optionName => $value) {
132
            foreach ($options as $optionName => $value) {
133
                $this->setOption($optionName);
133
                $this->setOption($optionName);
134
            }
134
            }
135
        }
135
        }
136
 
136
 
137
        if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) {
137
        if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) {
138
            $this->scheme = $reg[1];
138
            $this->scheme = $reg[1];
139
            $url = substr($url, strlen($reg[0]));
139
            $url = substr($url, strlen($reg[0]));
140
        }
140
        }
141
 
141
 
142
        if (preg_match('@^//([^/#?]+)@', $url, $reg)) {
142
        if (preg_match('@^//([^/#?]+)@', $url, $reg)) {
143
            $this->setAuthority($reg[1]);
143
            $this->setAuthority($reg[1]);
144
            $url = substr($url, strlen($reg[0]));
144
            $url = substr($url, strlen($reg[0]));
145
        }
145
        }
146
 
146
 
147
        $i = strcspn($url, '?#');
147
        $i = strcspn($url, '?#');
148
        $this->path = substr($url, 0, $i);
148
        $this->path = substr($url, 0, $i);
149
        $url = substr($url, $i);
149
        $url = substr($url, $i);
150
 
150
 
151
        if (preg_match('@^\?([^#]*)@', $url, $reg)) {
151
        if (preg_match('@^\?([^#]*)@', $url, $reg)) {
152
            $this->query = $reg[1];
152
            $this->query = $reg[1];
153
            $url = substr($url, strlen($reg[0]));
153
            $url = substr($url, strlen($reg[0]));
154
        }
154
        }
155
 
155
 
156
        if ($url) {
156
        if ($url) {
157
            $this->fragment = substr($url, 1);
157
            $this->fragment = substr($url, 1);
158
        }
158
        }
159
    }
159
    }
160
 
160
 
161
    /**
161
    /**
162
     * Returns the scheme, e.g. "http" or "urn", or false if there is no
162
     * Returns the scheme, e.g. "http" or "urn", or false if there is no
163
     * scheme specified, i.e. if this is a relative URL.
163
     * scheme specified, i.e. if this is a relative URL.
164
     *
164
     *
165
     * @return  string|bool
165
     * @return  string|bool
166
     */
166
     */
167
    public function getScheme()
167
    public function getScheme()
168
    {
168
    {
169
        return $this->scheme;
169
        return $this->scheme;
170
    }
170
    }
171
 
171
 
172
    /**
172
    /**
173
     * @param string|bool $scheme
173
     * @param string|bool $scheme
174
     *
174
     *
175
     * @return void
175
     * @return void
176
     * @see    getScheme()
176
     * @see    getScheme()
177
     */
177
     */
178
    public function setScheme($scheme)
178
    public function setScheme($scheme)
179
    {
179
    {
180
        $this->scheme = $scheme;
180
        $this->scheme = $scheme;
181
    }
181
    }
182
 
182
 
183
    /**
183
    /**
184
     * Returns the user part of the userinfo part (the part preceding the first
184
     * Returns the user part of the userinfo part (the part preceding the first
185
     *  ":"), or false if there is no userinfo part.
185
     *  ":"), or false if there is no userinfo part.
186
     *
186
     *
187
     * @return  string|bool
187
     * @return  string|bool
188
     */
188
     */
189
    public function getUser()
189
    public function getUser()
190
    {
190
    {
191
        return $this->userinfo !== false ? preg_replace('@:.*$@', '', $this->userinfo) : false;
191
        return $this->userinfo !== false ? preg_replace('@:.*$@', '', $this->userinfo) : false;
192
    }
192
    }
193
 
193
 
194
    /**
194
    /**
195
     * Returns the password part of the userinfo part (the part after the first
195
     * Returns the password part of the userinfo part (the part after the first
196
     *  ":"), or false if there is no userinfo part (i.e. the URL does not
196
     *  ":"), or false if there is no userinfo part (i.e. the URL does not
197
     * contain "@" in front of the hostname) or the userinfo part does not
197
     * contain "@" in front of the hostname) or the userinfo part does not
198
     * contain ":".
198
     * contain ":".
199
     *
199
     *
200
     * @return  string|bool
200
     * @return  string|bool
201
     */
201
     */
202
    public function getPassword()
202
    public function getPassword()
203
    {
203
    {
204
        return $this->userinfo !== false ? substr(strstr($this->userinfo, ':'), 1) : false;
204
        return $this->userinfo !== false ? substr(strstr($this->userinfo, ':'), 1) : false;
205
    }
205
    }
206
 
206
 
207
    /**
207
    /**
208
     * Returns the userinfo part, or false if there is none, i.e. if the
208
     * Returns the userinfo part, or false if there is none, i.e. if the
209
     * authority part does not contain "@".
209
     * authority part does not contain "@".
210
     *
210
     *
211
     * @return  string|bool
211
     * @return  string|bool
212
     */
212
     */
213
    public function getUserinfo()
213
    public function getUserinfo()
214
    {
214
    {
215
        return $this->userinfo;
215
        return $this->userinfo;
216
    }
216
    }
217
 
217
 
218
    /**
218
    /**
219
     * Sets the userinfo part. If two arguments are passed, they are combined
219
     * Sets the userinfo part. If two arguments are passed, they are combined
220
     * in the userinfo part as username ":" password.
220
     * in the userinfo part as username ":" password.
221
     *
221
     *
222
     * @param string|bool $userinfo userinfo or username
222
     * @param string|bool $userinfo userinfo or username
223
     * @param string|bool $password
223
     * @param string|bool $password
224
     *
224
     *
225
     * @return void
225
     * @return void
226
     */
226
     */
227
    public function setUserinfo($userinfo, $password = false)
227
    public function setUserinfo($userinfo, $password = false)
228
    {
228
    {
229
        $this->userinfo = $userinfo;
229
        $this->userinfo = $userinfo;
230
        if ($password !== false) {
230
        if ($password !== false) {
231
            $this->userinfo .= ':' . $password;
231
            $this->userinfo .= ':' . $password;
232
        }
232
        }
233
    }
233
    }
234
 
234
 
235
    /**
235
    /**
236
     * Returns the host part, or false if there is no authority part, e.g.
236
     * Returns the host part, or false if there is no authority part, e.g.
237
     * relative URLs.
237
     * relative URLs.
238
     *
238
     *
239
     * @return  string|bool
239
     * @return  string|bool
240
     */
240
     */
241
    public function getHost()
241
    public function getHost()
242
    {
242
    {
243
        return $this->host;
243
        return $this->host;
244
    }
244
    }
245
 
245
 
246
    /**
246
    /**
247
     * @param string|bool $host
247
     * @param string|bool $host
248
     *
248
     *
249
     * @return void
249
     * @return void
250
     */
250
     */
251
    public function setHost($host)
251
    public function setHost($host)
252
    {
252
    {
253
        $this->host = $host;
253
        $this->host = $host;
254
    }
254
    }
255
 
255
 
256
    /**
256
    /**
257
     * Returns the port number, or false if there is no port number specified,
257
     * Returns the port number, or false if there is no port number specified,
258
     * i.e. if the default port is to be used.
258
     * i.e. if the default port is to be used.
259
     *
259
     *
260
     * @return  int|bool
260
     * @return  int|bool
261
     */
261
     */
262
    public function getPort()
262
    public function getPort()
263
    {
263
    {
264
        return $this->port;
264
        return $this->port;
265
    }
265
    }
266
 
266
 
267
    /**
267
    /**
268
     * @param int|bool $port
268
     * @param int|bool $port
269
     *
269
     *
270
     * @return void
270
     * @return void
271
     */
271
     */
272
    public function setPort($port)
272
    public function setPort($port)
273
    {
273
    {
274
        $this->port = intval($port);
274
        $this->port = intval($port);
275
    }
275
    }
276
 
276
 
277
    /**
277
    /**
278
     * Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or
278
     * Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or
279
     * false if there is no authority none.
279
     * false if there is no authority none.
280
     *
280
     *
281
     * @return string|bool
281
     * @return string|bool
282
     */
282
     */
283
    public function getAuthority()
283
    public function getAuthority()
284
    {
284
    {
285
        if (!$this->host) {
285
        if (!$this->host) {
286
            return false;
286
            return false;
287
        }
287
        }
288
 
288
 
289
        $authority = '';
289
        $authority = '';
290
 
290
 
291
        if ($this->userinfo !== false) {
291
        if ($this->userinfo !== false) {
292
            $authority .= $this->userinfo . '@';
292
            $authority .= $this->userinfo . '@';
293
        }
293
        }
294
 
294
 
295
        $authority .= $this->host;
295
        $authority .= $this->host;
296
 
296
 
297
        if ($this->port !== false) {
297
        if ($this->port !== false) {
298
            $authority .= ':' . $this->port;
298
            $authority .= ':' . $this->port;
299
        }
299
        }
300
 
300
 
301
        return $authority;
301
        return $authority;
302
    }
302
    }
303
 
303
 
304
    /**
304
    /**
305
     * @param string|false $authority
305
     * @param string|false $authority
306
     *
306
     *
307
     * @return void
307
     * @return void
308
     */
308
     */
309
    public function setAuthority($authority)
309
    public function setAuthority($authority)
310
    {
310
    {
311
        $this->user = false;
311
        $this->user = false;
312
        $this->pass = false;
312
        $this->pass = false;
313
        $this->host = false;
313
        $this->host = false;
314
        $this->port = false;
314
        $this->port = false;
315
        if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
315
        if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
316
            if ($reg[1]) {
316
            if ($reg[1]) {
317
                $this->userinfo = $reg[2];
317
                $this->userinfo = $reg[2];
318
            }
318
            }
319
 
319
 
320
            $this->host = $reg[3];
320
            $this->host = $reg[3];
321
            if (isset($reg[5])) {
321
            if (isset($reg[5])) {
322
                $this->port = intval($reg[5]);
322
                $this->port = intval($reg[5]);
323
            }
323
            }
324
        }
324
        }
325
    }
325
    }
326
 
326
 
327
    /**
327
    /**
328
     * Returns the path part (possibly an empty string).
328
     * Returns the path part (possibly an empty string).
329
     *
329
     *
330
     * @return string
330
     * @return string
331
     */
331
     */
332
    public function getPath()
332
    public function getPath()
333
    {
333
    {
334
        return $this->path;
334
        return $this->path;
335
    }
335
    }
336
 
336
 
337
    /**
337
    /**
338
     * @param string $path
338
     * @param string $path
339
     *
339
     *
340
     * @return void
340
     * @return void
341
     */
341
     */
342
    public function setPath($path)
342
    public function setPath($path)
343
    {
343
    {
344
        $this->path = $path;
344
        $this->path = $path;
345
    }
345
    }
346
 
346
 
347
    /**
347
    /**
348
     * Returns the query string (excluding the leading "?"), or false if "?"
348
     * Returns the query string (excluding the leading "?"), or false if "?"
349
     * isn't present in the URL.
349
     * isn't present in the URL.
350
     *
350
     *
351
     * @return  string|bool
351
     * @return  string|bool
352
     * @see     self::getQueryVariables()
352
     * @see     self::getQueryVariables()
353
     */
353
     */
354
    public function getQuery()
354
    public function getQuery()
355
    {
355
    {
356
        return $this->query;
356
        return $this->query;
357
    }
357
    }
358
 
358
 
359
    /**
359
    /**
360
     * @param string|bool $query
360
     * @param string|bool $query
361
     *
361
     *
362
     * @return void
362
     * @return void
363
     * @see   self::setQueryVariables()
363
     * @see   self::setQueryVariables()
364
     */
364
     */
365
    public function setQuery($query)
365
    public function setQuery($query)
366
    {
366
    {
367
        $this->query = $query;
367
        $this->query = $query;
368
    }
368
    }
369
 
369
 
370
    /**
370
    /**
371
     * Returns the fragment name, or false if "#" isn't present in the URL.
371
     * Returns the fragment name, or false if "#" isn't present in the URL.
372
     *
372
     *
373
     * @return  string|bool
373
     * @return  string|bool
374
     */
374
     */
375
    public function getFragment()
375
    public function getFragment()
376
    {
376
    {
377
        return $this->fragment;
377
        return $this->fragment;
378
    }
378
    }
379
 
379
 
380
    /**
380
    /**
381
     * @param string|bool $fragment
381
     * @param string|bool $fragment
382
     *
382
     *
383
     * @return void
383
     * @return void
384
     */
384
     */
385
    public function setFragment($fragment)
385
    public function setFragment($fragment)
386
    {
386
    {
387
        $this->fragment = $fragment;
387
        $this->fragment = $fragment;
388
    }
388
    }
389
 
389
 
390
    /**
390
    /**
391
     * Returns the query string like an array as the variables would appear in
391
     * Returns the query string like an array as the variables would appear in
392
     * $_GET in a PHP script.
392
     * $_GET in a PHP script.
393
     *
393
     *
394
     * @return  array
394
     * @return  array
395
     */
395
     */
396
    public function getQueryVariables()
396
    public function getQueryVariables()
397
    {
397
    {
398
        $pattern = '/[' .
398
        $pattern = '/[' .
399
                   preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') .
399
                   preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') .
400
                   ']/';
400
                   ']/';
401
        $parts   = preg_split($pattern, $this->query, -1, PREG_SPLIT_NO_EMPTY);
401
        $parts   = preg_split($pattern, $this->query, -1, PREG_SPLIT_NO_EMPTY);
402
        $return  = array();
402
        $return  = array();
403
 
403
 
404
        foreach ($parts as $part) {
404
        foreach ($parts as $part) {
405
            if (strpos($part, '=') !== false) {
405
            if (strpos($part, '=') !== false) {
406
                list($key, $value) = explode('=', $part, 2);
406
                list($key, $value) = explode('=', $part, 2);
407
            } else {
407
            } else {
408
                $key   = $part;
408
                $key   = $part;
409
                $value = null;
409
                $value = null;
410
            }
410
            }
411
 
411
 
412
            if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
412
            if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
413
                $key = rawurldecode($key);
413
                $key = rawurldecode($key);
414
            }
414
            }
415
            $value = rawurldecode($value);
415
            $value = rawurldecode($value);
416
 
416
 
417
            if ($this->getOption(self::OPTION_USE_BRACKETS) &&
417
            if ($this->getOption(self::OPTION_USE_BRACKETS) &&
418
                preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) {
418
                preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) {
419
 
419
 
420
                $key = $matches[1];
420
                $key = $matches[1];
421
                $idx = $matches[2];
421
                $idx = $matches[2];
422
 
422
 
423
                // Ensure is an array
423
                // Ensure is an array
424
                if (empty($return[$key]) || !is_array($return[$key])) {
424
                if (empty($return[$key]) || !is_array($return[$key])) {
425
                    $return[$key] = array();
425
                    $return[$key] = array();
426
                }
426
                }
427
 
427
 
428
                // Add data
428
                // Add data
429
                if ($idx === '') {
429
                if ($idx === '') {
430
                    $return[$key][] = $value;
430
                    $return[$key][] = $value;
431
                } else {
431
                } else {
432
                    $return[$key][$idx] = $value;
432
                    $return[$key][$idx] = $value;
433
                }
433
                }
434
            } elseif (!$this->getOption(self::OPTION_USE_BRACKETS)
434
            } elseif (!$this->getOption(self::OPTION_USE_BRACKETS)
435
                      && !empty($return[$key])
435
                      && !empty($return[$key])
436
            ) {
436
            ) {
437
                $return[$key]   = (array) $return[$key];
437
                $return[$key]   = (array) $return[$key];
438
                $return[$key][] = $value;
438
                $return[$key][] = $value;
439
            } else {
439
            } else {
440
                $return[$key] = $value;
440
                $return[$key] = $value;
441
            }
441
            }
442
        }
442
        }
443
 
443
 
444
        return $return;
444
        return $return;
445
    }
445
    }
446
 
446
 
447
    /**
447
    /**
448
     * @param array $array (name => value) array
448
     * @param array $array (name => value) array
449
     *
449
     *
450
     * @return void
450
     * @return void
451
     */
451
     */
452
    public function setQueryVariables(array $array)
452
    public function setQueryVariables(array $array)
453
    {
453
    {
454
        if (!$array) {
454
        if (!$array) {
455
            $this->query = false;
455
            $this->query = false;
456
        } else {
456
        } else {
457
            foreach ($array as $name => $value) {
457
            foreach ($array as $name => $value) {
458
                if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
458
                if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
459
                    $name = rawurlencode($name);
459
                    $name = rawurlencode($name);
460
                }
460
                }
461
 
461
 
462
                if (is_array($value)) {
462
                if (is_array($value)) {
463
                    foreach ($value as $k => $v) {
463
                    foreach ($value as $k => $v) {
464
                        $parts[] = $this->getOption(self::OPTION_USE_BRACKETS)
464
                        $parts[] = $this->getOption(self::OPTION_USE_BRACKETS)
465
                            ? sprintf('%s[%s]=%s', $name, $k, $v)
465
                            ? sprintf('%s[%s]=%s', $name, $k, $v)
466
                            : ($name . '=' . $v);
466
                            : ($name . '=' . $v);
467
                    }
467
                    }
468
                } elseif (!is_null($value)) {
468
                } elseif (!is_null($value)) {
469
                    $parts[] = $name . '=' . $value;
469
                    $parts[] = $name . '=' . $value;
470
                } else {
470
                } else {
471
                    $parts[] = $name;
471
                    $parts[] = $name;
472
                }
472
                }
473
            }
473
            }
474
            $this->query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
474
            $this->query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
475
                                   $parts);
475
                                   $parts);
476
        }
476
        }
477
    }
477
    }
478
 
478
 
479
    /**
479
    /**
480
     * @param string $name
480
     * @param string $name
481
     * @param mixed  $value
481
     * @param mixed  $value
482
     *
482
     *
483
     * @return  array
483
     * @return  array
484
     */
484
     */
485
    public function setQueryVariable($name, $value)
485
    public function setQueryVariable($name, $value)
486
    {
486
    {
487
        $array = $this->getQueryVariables();
487
        $array = $this->getQueryVariables();
488
        $array[$name] = $value;
488
        $array[$name] = $value;
489
        $this->setQueryVariables($array);
489
        $this->setQueryVariables($array);
490
    }
490
    }
491
 
491
 
492
    /**
492
    /**
493
     * @param string $name
493
     * @param string $name
494
     *
494
     *
495
     * @return void
495
     * @return void
496
     */
496
     */
497
    public function unsetQueryVariable($name)
497
    public function unsetQueryVariable($name)
498
    {
498
    {
499
        $array = $this->getQueryVariables();
499
        $array = $this->getQueryVariables();
500
        unset($array[$name]);
500
        unset($array[$name]);
501
        $this->setQueryVariables($array);
501
        $this->setQueryVariables($array);
502
    }
502
    }
503
 
503
 
504
    /**
504
    /**
505
     * Returns a string representation of this URL.
505
     * Returns a string representation of this URL.
506
     *
506
     *
507
     * @return  string
507
     * @return  string
508
     */
508
     */
509
    public function getURL()
509
    public function getURL()
510
    {
510
    {
511
        // See RFC 3986, section 5.3
511
        // See RFC 3986, section 5.3
512
        $url = "";
512
        $url = "";
513
 
513
 
514
        if ($this->scheme !== false) {
514
        if ($this->scheme !== false) {
515
            $url .= $this->scheme . ':';
515
            $url .= $this->scheme . ':';
516
        }
516
        }
517
 
517
 
518
        $authority = $this->getAuthority();
518
        $authority = $this->getAuthority();
519
        if ($authority !== false) {
519
        if ($authority !== false) {
520
            $url .= '//' . $authority;
520
            $url .= '//' . $authority;
521
        }
521
        }
522
        $url .= $this->path;
522
        $url .= $this->path;
523
 
523
 
524
        if ($this->query !== false) {
524
        if ($this->query !== false) {
525
            $url .= '?' . $this->query;
525
            $url .= '?' . $this->query;
526
        }
526
        }
527
 
527
 
528
        if ($this->fragment !== false) {
528
        if ($this->fragment !== false) {
529
            $url .= '#' . $this->fragment;
529
            $url .= '#' . $this->fragment;
530
        }
530
        }
531
    
531
    
532
        return $url;
532
        return $url;
533
    }
533
    }
534
 
534
 
535
    /** 
535
    /** 
536
     * Returns a normalized string representation of this URL. This is useful
536
     * Returns a normalized string representation of this URL. This is useful
537
     * for comparison of URLs.
537
     * for comparison of URLs.
538
     *
538
     *
539
     * @return  string
539
     * @return  string
540
     */
540
     */
541
    public function getNormalizedURL()
541
    public function getNormalizedURL()
542
    {
542
    {
543
        $url = clone $this;
543
        $url = clone $this;
544
        $url->normalize();
544
        $url->normalize();
545
        return $url->getUrl();
545
        return $url->getUrl();
546
    }
546
    }
547
 
547
 
548
    /** 
548
    /** 
549
     * Returns a normalized Net_URL2 instance.
549
     * Returns a normalized Net_URL2 instance.
550
     *
550
     *
551
     * @return  Net_URL2
551
     * @return  Net_URL2
552
     */
552
     */
553
    public function normalize()
553
    public function normalize()
554
    {
554
    {
555
        // See RFC 3886, section 6
555
        // See RFC 3886, section 6
556
 
556
 
557
        // Schemes are case-insensitive
557
        // Schemes are case-insensitive
558
        if ($this->scheme) {
558
        if ($this->scheme) {
559
            $this->scheme = strtolower($this->scheme);
559
            $this->scheme = strtolower($this->scheme);
560
        }
560
        }
561
 
561
 
562
        // Hostnames are case-insensitive
562
        // Hostnames are case-insensitive
563
        if ($this->host) {
563
        if ($this->host) {
564
            $this->host = strtolower($this->host);
564
            $this->host = strtolower($this->host);
565
        }
565
        }
566
 
566
 
567
        // Remove default port number for known schemes (RFC 3986, section 6.2.3)
567
        // Remove default port number for known schemes (RFC 3986, section 6.2.3)
568
        if ($this->port &&
568
        if ($this->port &&
569
            $this->scheme &&
569
            $this->scheme &&
570
            $this->port == getservbyname($this->scheme, 'tcp')) {
570
            $this->port == getservbyname($this->scheme, 'tcp')) {
571
 
571
 
572
            $this->port = false;
572
            $this->port = false;
573
        }
573
        }
574
 
574
 
575
        // Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
575
        // Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
576
        foreach (array('userinfo', 'host', 'path') as $part) {
576
        foreach (array('userinfo', 'host', 'path') as $part) {
577
            if ($this->$part) {
577
            if ($this->$part) {
578
                $this->$part  = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$part);
578
                $this->$part  = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$part);
579
            }
579
            }
580
        }
580
        }
581
 
581
 
582
        // Path segment normalization (RFC 3986, section 6.2.2.3)
582
        // Path segment normalization (RFC 3986, section 6.2.2.3)
583
        $this->path = self::removeDotSegments($this->path);
583
        $this->path = self::removeDotSegments($this->path);
584
 
584
 
585
        // Scheme based normalization (RFC 3986, section 6.2.3)
585
        // Scheme based normalization (RFC 3986, section 6.2.3)
586
        if ($this->host && !$this->path) {
586
        if ($this->host && !$this->path) {
587
            $this->path = '/';
587
            $this->path = '/';
588
        }
588
        }
589
    }
589
    }
590
 
590
 
591
    /**
591
    /**
592
     * Returns whether this instance represents an absolute URL.
592
     * Returns whether this instance represents an absolute URL.
593
     *
593
     *
594
     * @return  bool
594
     * @return  bool
595
     */
595
     */
596
    public function isAbsolute()
596
    public function isAbsolute()
597
    {
597
    {
598
        return (bool) $this->scheme;
598
        return (bool) $this->scheme;
599
    }
599
    }
600
 
600
 
601
    /**
601
    /**
602
     * Returns an Net_URL2 instance representing an absolute URL relative to
602
     * Returns an Net_URL2 instance representing an absolute URL relative to
603
     * this URL.
603
     * this URL.
604
     *
604
     *
605
     * @param Net_URL2|string $reference relative URL
605
     * @param Net_URL2|string $reference relative URL
606
     *
606
     *
607
     * @return Net_URL2
607
     * @return Net_URL2
608
     */
608
     */
609
    public function resolve($reference)
609
    public function resolve($reference)
610
    {
610
    {
611
        if (is_string($reference)) {
611
        if (is_string($reference)) {
612
            $reference = new self($reference);
612
            $reference = new self($reference);
613
        }
613
        }
614
        if (!$this->isAbsolute()) {
614
        if (!$this->isAbsolute()) {
615
            throw new Exception('Base-URL must be absolute');
615
            throw new Exception('Base-URL must be absolute');
616
        }
616
        }
617
 
617
 
618
        // A non-strict parser may ignore a scheme in the reference if it is
618
        // A non-strict parser may ignore a scheme in the reference if it is
619
        // identical to the base URI's scheme.
619
        // identical to the base URI's scheme.
620
        if (!$this->getOption(self::OPTION_STRICT) && $reference->scheme == $this->scheme) {
620
        if (!$this->getOption(self::OPTION_STRICT) && $reference->scheme == $this->scheme) {
621
            $reference->scheme = false;
621
            $reference->scheme = false;
622
        }
622
        }
623
 
623
 
624
        $target = new self('');
624
        $target = new self('');
625
        if ($reference->scheme !== false) {
625
        if ($reference->scheme !== false) {
626
            $target->scheme = $reference->scheme;
626
            $target->scheme = $reference->scheme;
627
            $target->setAuthority($reference->getAuthority());
627
            $target->setAuthority($reference->getAuthority());
628
            $target->path  = self::removeDotSegments($reference->path);
628
            $target->path  = self::removeDotSegments($reference->path);
629
            $target->query = $reference->query;
629
            $target->query = $reference->query;
630
        } else {
630
        } else {
631
            $authority = $reference->getAuthority();
631
            $authority = $reference->getAuthority();
632
            if ($authority !== false) {
632
            if ($authority !== false) {
633
                $target->setAuthority($authority);
633
                $target->setAuthority($authority);
634
                $target->path  = self::removeDotSegments($reference->path);
634
                $target->path  = self::removeDotSegments($reference->path);
635
                $target->query = $reference->query;
635
                $target->query = $reference->query;
636
            } else {
636
            } else {
637
                if ($reference->path == '') {
637
                if ($reference->path == '') {
638
                    $target->path = $this->path;
638
                    $target->path = $this->path;
639
                    if ($reference->query !== false) {
639
                    if ($reference->query !== false) {
640
                        $target->query = $reference->query;
640
                        $target->query = $reference->query;
641
                    } else {
641
                    } else {
642
                        $target->query = $this->query;
642
                        $target->query = $this->query;
643
                    }
643
                    }
644
                } else {
644
                } else {
645
                    if (substr($reference->path, 0, 1) == '/') {
645
                    if (substr($reference->path, 0, 1) == '/') {
646
                        $target->path = self::removeDotSegments($reference->path);
646
                        $target->path = self::removeDotSegments($reference->path);
647
                    } else {
647
                    } else {
648
                        // Merge paths (RFC 3986, section 5.2.3)
648
                        // Merge paths (RFC 3986, section 5.2.3)
649
                        if ($this->host !== false && $this->path == '') {
649
                        if ($this->host !== false && $this->path == '') {
650
                            $target->path = '/' . $this->path;
650
                            $target->path = '/' . $this->path;
651
                        } else {
651
                        } else {
652
                            $i = strrpos($this->path, '/');
652
                            $i = strrpos($this->path, '/');
653
                            if ($i !== false) {
653
                            if ($i !== false) {
654
                                $target->path = substr($this->path, 0, $i + 1);
654
                                $target->path = substr($this->path, 0, $i + 1);
655
                            }
655
                            }
656
                            $target->path .= $reference->path;
656
                            $target->path .= $reference->path;
657
                        }
657
                        }
658
                        $target->path = self::removeDotSegments($target->path);
658
                        $target->path = self::removeDotSegments($target->path);
659
                    }
659
                    }
660
                    $target->query = $reference->query;
660
                    $target->query = $reference->query;
661
                }
661
                }
662
                $target->setAuthority($this->getAuthority());
662
                $target->setAuthority($this->getAuthority());
663
            }
663
            }
664
            $target->scheme = $this->scheme;
664
            $target->scheme = $this->scheme;
665
        }
665
        }
666
 
666
 
667
        $target->fragment = $reference->fragment;
667
        $target->fragment = $reference->fragment;
668
 
668
 
669
        return $target;
669
        return $target;
670
    }
670
    }
671
 
671
 
672
    /**
672
    /**
673
     * Removes dots as described in RFC 3986, section 5.2.4, e.g.
673
     * Removes dots as described in RFC 3986, section 5.2.4, e.g.
674
     * "/foo/../bar/baz" => "/bar/baz"
674
     * "/foo/../bar/baz" => "/bar/baz"
675
     *
675
     *
676
     * @param string $path a path
676
     * @param string $path a path
677
     *
677
     *
678
     * @return string a path
678
     * @return string a path
679
     */
679
     */
680
    private static function removeDotSegments($path)
680
    private static function removeDotSegments($path)
681
    {
681
    {
682
        $output = '';
682
        $output = '';
683
 
683
 
684
        // Make sure not to be trapped in an infinite loop due to a bug in this
684
        // Make sure not to be trapped in an infinite loop due to a bug in this
685
        // method
685
        // method
686
        $j = 0; 
686
        $j = 0; 
687
        while ($path && $j++ < 100) {
687
        while ($path && $j++ < 100) {
688
            // Step A
688
            // Step A
689
            if (substr($path, 0, 2) == './') {
689
            if (substr($path, 0, 2) == './') {
690
                $path = substr($path, 2);
690
                $path = substr($path, 2);
691
            } elseif (substr($path, 0, 3) == '../') {
691
            } elseif (substr($path, 0, 3) == '../') {
692
                $path = substr($path, 3);
692
                $path = substr($path, 3);
693
 
693
 
694
            // Step B
694
            // Step B
695
            } elseif (substr($path, 0, 3) == '/./' || $path == '/.') {
695
            } elseif (substr($path, 0, 3) == '/./' || $path == '/.') {
696
                $path = '/' . substr($path, 3);
696
                $path = '/' . substr($path, 3);
697
 
697
 
698
            // Step C
698
            // Step C
699
            } elseif (substr($path, 0, 4) == '/../' || $path == '/..') {
699
            } elseif (substr($path, 0, 4) == '/../' || $path == '/..') {
700
                $path = '/' . substr($path, 4);
700
                $path = '/' . substr($path, 4);
701
                $i = strrpos($output, '/');
701
                $i = strrpos($output, '/');
702
                $output = $i === false ? '' : substr($output, 0, $i);
702
                $output = $i === false ? '' : substr($output, 0, $i);
703
 
703
 
704
            // Step D
704
            // Step D
705
            } elseif ($path == '.' || $path == '..') {
705
            } elseif ($path == '.' || $path == '..') {
706
                $path = '';
706
                $path = '';
707
 
707
 
708
            // Step E
708
            // Step E
709
            } else {
709
            } else {
710
                $i = strpos($path, '/');
710
                $i = strpos($path, '/');
711
                if ($i === 0) {
711
                if ($i === 0) {
712
                    $i = strpos($path, '/', 1);
712
                    $i = strpos($path, '/', 1);
713
                }
713
                }
714
                if ($i === false) {
714
                if ($i === false) {
715
                    $i = strlen($path);
715
                    $i = strlen($path);
716
                }
716
                }
717
                $output .= substr($path, 0, $i);
717
                $output .= substr($path, 0, $i);
718
                $path = substr($path, $i);
718
                $path = substr($path, $i);
719
            }
719
            }
720
        }
720
        }
721
 
721
 
722
        return $output;
722
        return $output;
723
    }
723
    }
724
 
724
 
725
    /**
725
    /**
726
     * Returns a Net_URL2 instance representing the canonical URL of the
726
     * Returns a Net_URL2 instance representing the canonical URL of the
727
     * currently executing PHP script.
727
     * currently executing PHP script.
728
     * 
728
     * 
729
     * @return  string
729
     * @return  string
730
     */
730
     */
731
    public static function getCanonical()
731
    public static function getCanonical()
732
    {
732
    {
733
        if (!isset($_SERVER['REQUEST_METHOD'])) {
733
        if (!isset($_SERVER['REQUEST_METHOD'])) {
734
            // ALERT - no current URL
734
            // ALERT - no current URL
735
            throw new Exception('Script was not called through a webserver');
735
            throw new Exception('Script was not called through a webserver');
736
        }
736
        }
737
 
737
 
738
        // Begin with a relative URL
738
        // Begin with a relative URL
739
        $url = new self($_SERVER['PHP_SELF']);
739
        $url = new self($_SERVER['PHP_SELF']);
740
        $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
740
        $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
741
        $url->host = $_SERVER['SERVER_NAME'];
741
        $url->host = $_SERVER['SERVER_NAME'];
742
        $port = intval($_SERVER['SERVER_PORT']);
742
        $port = intval($_SERVER['SERVER_PORT']);
743
        if ($url->scheme == 'http' && $port != 80 ||
743
        if ($url->scheme == 'http' && $port != 80 ||
744
            $url->scheme == 'https' && $port != 443) {
744
            $url->scheme == 'https' && $port != 443) {
745
 
745
 
746
            $url->port = $port;
746
            $url->port = $port;
747
        }
747
        }
748
        return $url;
748
        return $url;
749
    }
749
    }
750
 
750
 
751
    /**
751
    /**
752
     * Returns the URL used to retrieve the current request.
752
     * Returns the URL used to retrieve the current request.
753
     *
753
     *
754
     * @return  string
754
     * @return  string
755
     */
755
     */
756
    public static function getRequestedURL()
756
    public static function getRequestedURL()
757
    {
757
    {
758
        return self::getRequested()->getUrl();
758
        return self::getRequested()->getUrl();
759
    }
759
    }
760
 
760
 
761
    /**
761
    /**
762
     * Returns a Net_URL2 instance representing the URL used to retrieve the
762
     * Returns a Net_URL2 instance representing the URL used to retrieve the
763
     * current request.
763
     * current request.
764
     *
764
     *
765
     * @return  Net_URL2
765
     * @return  Net_URL2
766
     */
766
     */
767
    public static function getRequested()
767
    public static function getRequested()
768
    {
768
    {
769
        if (!isset($_SERVER['REQUEST_METHOD'])) {
769
        if (!isset($_SERVER['REQUEST_METHOD'])) {
770
            // ALERT - no current URL
770
            // ALERT - no current URL
771
            throw new Exception('Script was not called through a webserver');
771
            throw new Exception('Script was not called through a webserver');
772
        }
772
        }
773
 
773
 
774
        // Begin with a relative URL
774
        // Begin with a relative URL
775
        $url = new self($_SERVER['REQUEST_URI']);
775
        $url = new self($_SERVER['REQUEST_URI']);
776
        $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
776
        $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
777
        // Set host and possibly port
777
        // Set host and possibly port
778
        $url->setAuthority($_SERVER['HTTP_HOST']);
778
        $url->setAuthority($_SERVER['HTTP_HOST']);
779
        return $url;
779
        return $url;
780
    }
780
    }
781
 
781
 
782
    /**
782
    /**
783
     * Sets the specified option.
783
     * Sets the specified option.
784
     *
784
     *
785
     * @param string $optionName a self::OPTION_ constant
785
     * @param string $optionName a self::OPTION_ constant
786
     * @param mixed  $value      option value  
786
     * @param mixed  $value      option value  
787
     *
787
     *
788
     * @return void
788
     * @return void
789
     * @see  self::OPTION_STRICT
789
     * @see  self::OPTION_STRICT
790
     * @see  self::OPTION_USE_BRACKETS
790
     * @see  self::OPTION_USE_BRACKETS
791
     * @see  self::OPTION_ENCODE_KEYS
791
     * @see  self::OPTION_ENCODE_KEYS
792
     */
792
     */
793
    function setOption($optionName, $value)
793
    function setOption($optionName, $value)
794
    {
794
    {
795
        if (!array_key_exists($optionName, $this->options)) {
795
        if (!array_key_exists($optionName, $this->options)) {
796
            return false;
796
            return false;
797
        }
797
        }
798
        $this->options[$optionName] = $value;
798
        $this->options[$optionName] = $value;
799
    }
799
    }
800
 
800
 
801
    /**
801
    /**
802
     * Returns the value of the specified option.
802
     * Returns the value of the specified option.
803
     *
803
     *
804
     * @param string $optionName The name of the option to retrieve
804
     * @param string $optionName The name of the option to retrieve
805
     *
805
     *
806
     * @return  mixed
806
     * @return  mixed
807
     */
807
     */
808
    function getOption($optionName)
808
    function getOption($optionName)
809
    {
809
    {
810
        return isset($this->options[$optionName])
810
        return isset($this->options[$optionName])
811
            ? $this->options[$optionName] : false;
811
            ? $this->options[$optionName] : false;
812
    }
812
    }
813
    
813
    
814
    public function __toString() {
814
    public function __toString() {
815
    	return $this->getURL();
815
    	return $this->getURL();
816
    }
816
    }
817
}
817
}