Overview

Packages

  • None
  • SimplePie

Classes

  • SimplePie
  • SimplePie_Author
  • SimplePie_Autoloader
  • SimplePie_Cache
  • SimplePie_Cache_DB
  • SimplePie_Cache_File
  • SimplePie_Cache_Memcache
  • SimplePie_Cache_MySQL
  • SimplePie_Caption
  • SimplePie_Category
  • SimplePie_Content_Type_Sniffer
  • SimplePie_Copyright
  • SimplePie_Core
  • SimplePie_Credit
  • SimplePie_Decode_HTML_Entities
  • SimplePie_Enclosure
  • SimplePie_File
  • SimplePie_gzdecode
  • SimplePie_HTTP_Parser
  • SimplePie_IRI
  • SimplePie_Item
  • SimplePie_Locator
  • SimplePie_Misc
  • SimplePie_Net_IPv6
  • SimplePie_Parse_Date
  • SimplePie_Parser
  • SimplePie_Rating
  • SimplePie_Registry
  • SimplePie_Restriction
  • SimplePie_Sanitize
  • SimplePie_Source
  • SimplePie_XML_Declaration_Parser

Interfaces

  • SimplePie_Cache_Base
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * SimplePie
  4:  *
  5:  * A PHP-Based RSS and Atom Feed Framework.
  6:  * Takes the hard work out of managing a complete RSS/Atom solution.
  7:  *
  8:  * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
  9:  * All rights reserved.
 10:  *
 11:  * Redistribution and use in source and binary forms, with or without modification, are
 12:  * permitted provided that the following conditions are met:
 13:  *
 14:  *  * Redistributions of source code must retain the above copyright notice, this list of
 15:  *    conditions and the following disclaimer.
 16:  *
 17:  *  * Redistributions in binary form must reproduce the above copyright notice, this list
 18:  *    of conditions and the following disclaimer in the documentation and/or other materials
 19:  *    provided with the distribution.
 20:  *
 21:  *  * Neither the name of the SimplePie Team nor the names of its contributors may be used
 22:  *    to endorse or promote products derived from this software without specific prior
 23:  *    written permission.
 24:  *
 25:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 26:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 27:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
 28:  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 29:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 30:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 31:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 32:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 33:  * POSSIBILITY OF SUCH DAMAGE.
 34:  *
 35:  * @package SimplePie
 36:  * @version 1.3-dev
 37:  * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
 38:  * @author Ryan Parman
 39:  * @author Geoffrey Sneddon
 40:  * @author Ryan McCue
 41:  * @link http://simplepie.org/ SimplePie
 42:  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
 43:  */
 44: 
 45: /**
 46:  * IRI parser/serialiser
 47:  *
 48:  * @package SimplePie
 49:  */
 50: class SimplePie_IRI
 51: {
 52:     /**
 53:      * Scheme
 54:      *
 55:      * @access private
 56:      * @var string
 57:      */
 58:     var $scheme;
 59: 
 60:     /**
 61:      * User Information
 62:      *
 63:      * @access private
 64:      * @var string
 65:      */
 66:     var $userinfo;
 67: 
 68:     /**
 69:      * Host
 70:      *
 71:      * @access private
 72:      * @var string
 73:      */
 74:     var $host;
 75: 
 76:     /**
 77:      * Port
 78:      *
 79:      * @access private
 80:      * @var string
 81:      */
 82:     var $port;
 83: 
 84:     /**
 85:      * Path
 86:      *
 87:      * @access private
 88:      * @var string
 89:      */
 90:     var $path;
 91: 
 92:     /**
 93:      * Query
 94:      *
 95:      * @access private
 96:      * @var string
 97:      */
 98:     var $query;
 99: 
100:     /**
101:      * Fragment
102:      *
103:      * @access private
104:      * @var string
105:      */
106:     var $fragment;
107: 
108:     /**
109:      * Whether the object represents a valid IRI
110:      *
111:      * @access private
112:      * @var array
113:      */
114:     var $valid = array();
115: 
116:     /**
117:      * Return the entire IRI when you try and read the object as a string
118:      *
119:      * @access public
120:      * @return string
121:      */
122:     public function __toString()
123:     {
124:         return $this->get_iri();
125:     }
126: 
127:     /**
128:      * Create a new IRI object, from a specified string
129:      *
130:      * @access public
131:      * @param string $iri
132:      * @return SimplePie_IRI
133:      */
134:     public function __construct($iri)
135:     {
136:         $iri = (string) $iri;
137:         if ($iri !== '')
138:         {
139:             $parsed = $this->parse_iri($iri);
140:             $this->set_scheme($parsed['scheme']);
141:             $this->set_authority($parsed['authority']);
142:             $this->set_path($parsed['path']);
143:             $this->set_query($parsed['query']);
144:             $this->set_fragment($parsed['fragment']);
145:         }
146:     }
147: 
148:     /**
149:      * Create a new IRI object by resolving a relative IRI
150:      *
151:      * @static
152:      * @access public
153:      * @param SimplePie_IRI $base Base IRI
154:      * @param string $relative Relative IRI
155:      * @return SimplePie_IRI
156:      */
157:     public static function absolutize($base, $relative)
158:     {
159:         $relative = (string) $relative;
160:         if ($relative !== '')
161:         {
162:             $relative = new SimplePie_IRI($relative);
163:             if ($relative->get_scheme() !== null)
164:             {
165:                 $target = $relative;
166:             }
167:             elseif ($base->get_iri() !== null)
168:             {
169:                 if ($relative->get_authority() !== null)
170:                 {
171:                     $target = $relative;
172:                     $target->set_scheme($base->get_scheme());
173:                 }
174:                 else
175:                 {
176:                     $target = new SimplePie_IRI('');
177:                     $target->set_scheme($base->get_scheme());
178:                     $target->set_userinfo($base->get_userinfo());
179:                     $target->set_host($base->get_host());
180:                     $target->set_port($base->get_port());
181:                     if ($relative->get_path() !== null)
182:                     {
183:                         if (strpos($relative->get_path(), '/') === 0)
184:                         {
185:                             $target->set_path($relative->get_path());
186:                         }
187:                         elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
188:                         {
189:                             $target->set_path('/' . $relative->get_path());
190:                         }
191:                         elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
192:                         {
193:                             $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
194:                         }
195:                         else
196:                         {
197:                             $target->set_path($relative->get_path());
198:                         }
199:                         $target->set_query($relative->get_query());
200:                     }
201:                     else
202:                     {
203:                         $target->set_path($base->get_path());
204:                         if ($relative->get_query() !== null)
205:                         {
206:                             $target->set_query($relative->get_query());
207:                         }
208:                         elseif ($base->get_query() !== null)
209:                         {
210:                             $target->set_query($base->get_query());
211:                         }
212:                     }
213:                 }
214:                 $target->set_fragment($relative->get_fragment());
215:             }
216:             else
217:             {
218:                 // No base URL, just return the relative URL
219:                 $target = $relative;
220:             }
221:         }
222:         else
223:         {
224:             $target = $base;
225:         }
226:         return $target;
227:     }
228: 
229:     /**
230:      * Parse an IRI into scheme/authority/path/query/fragment segments
231:      *
232:      * @access private
233:      * @param string $iri
234:      * @return array
235:      */
236:     public function parse_iri($iri)
237:     {
238:         preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
239:         for ($i = count($match); $i <= 9; $i++)
240:         {
241:             $match[$i] = '';
242:         }
243:         return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
244:     }
245: 
246:     /**
247:      * Remove dot segments from a path
248:      *
249:      * @access private
250:      * @param string $input
251:      * @return string
252:      */
253:     public function remove_dot_segments($input)
254:     {
255:         $output = '';
256:         while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
257:         {
258:             // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
259:             if (strpos($input, '../') === 0)
260:             {
261:                 $input = substr($input, 3);
262:             }
263:             elseif (strpos($input, './') === 0)
264:             {
265:                 $input = substr($input, 2);
266:             }
267:             // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
268:             elseif (strpos($input, '/./') === 0)
269:             {
270:                 $input = substr_replace($input, '/', 0, 3);
271:             }
272:             elseif ($input === '/.')
273:             {
274:                 $input = '/';
275:             }
276:             // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
277:             elseif (strpos($input, '/../') === 0)
278:             {
279:                 $input = substr_replace($input, '/', 0, 4);
280:                 $output = substr_replace($output, '', strrpos($output, '/'));
281:             }
282:             elseif ($input === '/..')
283:             {
284:                 $input = '/';
285:                 $output = substr_replace($output, '', strrpos($output, '/'));
286:             }
287:             // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
288:             elseif ($input === '.' || $input === '..')
289:             {
290:                 $input = '';
291:             }
292:             // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
293:             elseif (($pos = strpos($input, '/', 1)) !== false)
294:             {
295:                 $output .= substr($input, 0, $pos);
296:                 $input = substr_replace($input, '', 0, $pos);
297:             }
298:             else
299:             {
300:                 $output .= $input;
301:                 $input = '';
302:             }
303:         }
304:         return $output . $input;
305:     }
306: 
307:     /**
308:      * Replace invalid character with percent encoding
309:      *
310:      * @param string $string Input string
311:      * @param string $valid_chars Valid characters not in iunreserved or iprivate (this is ASCII-only)
312:      * @param int $case Normalise case
313:      * @param bool $iprivate Allow iprivate
314:      * @return string
315:      */
316:     protected function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE, $iprivate = false)
317:     {
318:         // Normalize as many pct-encoded sections as possible
319:         $string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array(&$this, 'remove_iunreserved_percent_encoded'), $string);
320: 
321:         // Replace invalid percent characters
322:         $string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
323: 
324:         // Add unreserved and % to $valid_chars (the latter is safe because all
325:         // pct-encoded sections are now valid).
326:         $valid_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
327: 
328:         // Now replace any bytes that aren't allowed with their pct-encoded versions
329:         $position = 0;
330:         $strlen = strlen($string);
331:         while (($position += strspn($string, $valid_chars, $position)) < $strlen)
332:         {
333:             $value = ord($string[$position]);
334: 
335:             // Start position
336:             $start = $position;
337: 
338:             // By default we are valid
339:             $valid = true;
340: 
341:             // No one byte sequences are valid due to the while.
342:             // Two byte sequence:
343:             if (($value & 0xE0) === 0xC0)
344:             {
345:                 $character = ($value & 0x1F) << 6;
346:                 $length = 2;
347:                 $remaining = 1;
348:             }
349:             // Three byte sequence:
350:             elseif (($value & 0xF0) === 0xE0)
351:             {
352:                 $character = ($value & 0x0F) << 12;
353:                 $length = 3;
354:                 $remaining = 2;
355:             }
356:             // Four byte sequence:
357:             elseif (($value & 0xF8) === 0xF0)
358:             {
359:                 $character = ($value & 0x07) << 18;
360:                 $length = 4;
361:                 $remaining = 3;
362:             }
363:             // Invalid byte:
364:             else
365:             {
366:                 $valid = false;
367:                 $length = 1;
368:                 $remaining = 0;
369:             }
370: 
371:             if ($remaining)
372:             {
373:                 if ($position + $length <= $strlen)
374:                 {
375:                     for ($position++; $remaining; $position++)
376:                     {
377:                         $value = ord($string[$position]);
378: 
379:                         // Check that the byte is valid, then add it to the character:
380:                         if (($value & 0xC0) === 0x80)
381:                         {
382:                             $character |= ($value & 0x3F) << (--$remaining * 6);
383:                         }
384:                         // If it is invalid, count the sequence as invalid and reprocess the current byte:
385:                         else
386:                         {
387:                             $valid = false;
388:                             $position--;
389:                             break;
390:                         }
391:                     }
392:                 }
393:                 else
394:                 {
395:                     $position = $strlen - 1;
396:                     $valid = false;
397:                 }
398:             }
399: 
400:             // Percent encode anything invalid or not in ucschar
401:             if (
402:                 // Invalid sequences
403:                 !$valid
404:                 // Non-shortest form sequences are invalid
405:                 || $length > 1 && $character <= 0x7F
406:                 || $length > 2 && $character <= 0x7FF
407:                 || $length > 3 && $character <= 0xFFFF
408:                 // Outside of range of ucschar codepoints
409:                 // Noncharacters
410:                 || ($character & 0xFFFE) === 0xFFFE
411:                 || $character >= 0xFDD0 && $character <= 0xFDEF
412:                 || (
413:                     // Everything else not in ucschar
414:                        $character > 0xD7FF && $character < 0xF900
415:                     || $character < 0xA0
416:                     || $character > 0xEFFFD
417:                 )
418:                 && (
419:                     // Everything not in iprivate, if it applies
420:                        !$iprivate
421:                     || $character < 0xE000
422:                     || $character > 0x10FFFD
423:                 )
424:             )
425:             {
426:                 // If we were a character, pretend we weren't, but rather an error.
427:                 if ($valid)
428:                     $position--;
429: 
430:                 for ($j = $start; $j <= $position; $j++)
431:                 {
432:                     $string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);
433:                     $j += 2;
434:                     $position += 2;
435:                     $strlen += 2;
436:                 }
437:             }
438:         }
439: 
440:         // Normalise case
441:         if ($case & SIMPLEPIE_LOWERCASE)
442:         {
443:             $string = strtolower($string);
444:         }
445:         elseif ($case & SIMPLEPIE_UPPERCASE)
446:         {
447:             $string = strtoupper($string);
448:         }
449: 
450:         return $string;
451:     }
452: 
453:     /**
454:      * Callback function for preg_replace_callback.
455:      *
456:      * Removes sequences of percent encoded bytes that represent UTF-8
457:      * encoded characters in iunreserved
458:      *
459:      * @param array $match PCRE match
460:      * @return string Replacement
461:      */
462:     protected function remove_iunreserved_percent_encoded($match)
463:     {
464:         // As we just have valid percent encoded sequences we can just explode
465:         // and ignore the first member of the returned array (an empty string).
466:         $bytes = explode('%', $match[0]);
467: 
468:         // Initialize the new string (this is what will be returned) and that
469:         // there are no bytes remaining in the current sequence (unsurprising
470:         // at the first byte!).
471:         $string = '';
472:         $remaining = 0;
473: 
474:         // Loop over each and every byte, and set $value to its value
475:         for ($i = 1, $len = count($bytes); $i < $len; $i++)
476:         {
477:             $value = hexdec($bytes[$i]);
478: 
479:             // If we're the first byte of sequence:
480:             if (!$remaining)
481:             {
482:                 // Start position
483:                 $start = $i;
484: 
485:                 // By default we are valid
486:                 $valid = true;
487: 
488:                 // One byte sequence:
489:                 if ($value <= 0x7F)
490:                 {
491:                     $character = $value;
492:                     $length = 1;
493:                 }
494:                 // Two byte sequence:
495:                 elseif (($value & 0xE0) === 0xC0)
496:                 {
497:                     $character = ($value & 0x1F) << 6;
498:                     $length = 2;
499:                     $remaining = 1;
500:                 }
501:                 // Three byte sequence:
502:                 elseif (($value & 0xF0) === 0xE0)
503:                 {
504:                     $character = ($value & 0x0F) << 12;
505:                     $length = 3;
506:                     $remaining = 2;
507:                 }
508:                 // Four byte sequence:
509:                 elseif (($value & 0xF8) === 0xF0)
510:                 {
511:                     $character = ($value & 0x07) << 18;
512:                     $length = 4;
513:                     $remaining = 3;
514:                 }
515:                 // Invalid byte:
516:                 else
517:                 {
518:                     $valid = false;
519:                     $remaining = 0;
520:                 }
521:             }
522:             // Continuation byte:
523:             else
524:             {
525:                 // Check that the byte is valid, then add it to the character:
526:                 if (($value & 0xC0) === 0x80)
527:                 {
528:                     $remaining--;
529:                     $character |= ($value & 0x3F) << ($remaining * 6);
530:                 }
531:                 // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
532:                 else
533:                 {
534:                     $valid = false;
535:                     $remaining = 0;
536:                     $i--;
537:                 }
538:             }
539: 
540:             // If we've reached the end of the current byte sequence, append it to Unicode::$data
541:             if (!$remaining)
542:             {
543:                 // Percent encode anything invalid or not in iunreserved
544:                 if (
545:                     // Invalid sequences
546:                     !$valid
547:                     // Non-shortest form sequences are invalid
548:                     || $length > 1 && $character <= 0x7F
549:                     || $length > 2 && $character <= 0x7FF
550:                     || $length > 3 && $character <= 0xFFFF
551:                     // Outside of range of iunreserved codepoints
552:                     || $character < 0x2D
553:                     || $character > 0xEFFFD
554:                     // Noncharacters
555:                     || ($character & 0xFFFE) === 0xFFFE
556:                     || $character >= 0xFDD0 && $character <= 0xFDEF
557:                     // Everything else not in iunreserved (this is all BMP)
558:                     || $character === 0x2F
559:                     || $character > 0x39 && $character < 0x41
560:                     || $character > 0x5A && $character < 0x61
561:                     || $character > 0x7A && $character < 0x7E
562:                     || $character > 0x7E && $character < 0xA0
563:                     || $character > 0xD7FF && $character < 0xF900
564:                 )
565:                 {
566:                     for ($j = $start; $j <= $i; $j++)
567:                     {
568:                         $string .= '%' . strtoupper($bytes[$j]);
569:                     }
570:                 }
571:                 else
572:                 {
573:                     for ($j = $start; $j <= $i; $j++)
574:                     {
575:                         $string .= chr(hexdec($bytes[$j]));
576:                     }
577:                 }
578:             }
579:         }
580: 
581:         // If we have any bytes left over they are invalid (i.e., we are
582:         // mid-way through a multi-byte sequence)
583:         if ($remaining)
584:         {
585:             for ($j = $start; $j < $len; $j++)
586:             {
587:                 $string .= '%' . strtoupper($bytes[$j]);
588:             }
589:         }
590: 
591:         return $string;
592:     }
593: 
594:     /**
595:      * Check if the object represents a valid IRI
596:      *
597:      * @access public
598:      * @return bool
599:      */
600:     public function is_valid()
601:     {
602:         return array_sum($this->valid) === count($this->valid);
603:     }
604: 
605:     /**
606:      * Set the scheme. Returns true on success, false on failure (if there are
607:      * any invalid characters).
608:      *
609:      * @access public
610:      * @param string $scheme
611:      * @return bool
612:      */
613:     public function set_scheme($scheme)
614:     {
615:         if ($scheme === null || $scheme === '')
616:         {
617:             $this->scheme = null;
618:         }
619:         else
620:         {
621:             $len = strlen($scheme);
622:             switch (true)
623:             {
624:                 case $len > 1:
625:                     if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
626:                     {
627:                         $this->scheme = null;
628:                         $this->valid[__FUNCTION__] = false;
629:                         return false;
630:                     }
631: 
632:                 case $len > 0:
633:                     if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
634:                     {
635:                         $this->scheme = null;
636:                         $this->valid[__FUNCTION__] = false;
637:                         return false;
638:                     }
639:             }
640:             $this->scheme = strtolower($scheme);
641:         }
642:         $this->valid[__FUNCTION__] = true;
643:         return true;
644:     }
645: 
646:     /**
647:      * Set the authority. Returns true on success, false on failure (if there are
648:      * any invalid characters).
649:      *
650:      * @access public
651:      * @param string $authority
652:      * @return bool
653:      */
654:     public function set_authority($authority)
655:     {
656:         if (($userinfo_end = strrpos($authority, '@')) !== false)
657:         {
658:             $userinfo = substr($authority, 0, $userinfo_end);
659:             $authority = substr($authority, $userinfo_end + 1);
660:         }
661:         else
662:         {
663:             $userinfo = null;
664:         }
665: 
666:         if (($port_start = strpos($authority, ':')) !== false)
667:         {
668:             $port = substr($authority, $port_start + 1);
669:             if ($port === false)
670:             {
671:                 $port = null;
672:             }
673:             $authority = substr($authority, 0, $port_start);
674:         }
675:         else
676:         {
677:             $port = null;
678:         }
679: 
680:         return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
681:     }
682: 
683:     /**
684:      * Set the userinfo.
685:      *
686:      * @access public
687:      * @param string $userinfo
688:      * @return bool
689:      */
690:     public function set_userinfo($userinfo)
691:     {
692:         if ($userinfo === null || $userinfo === '')
693:         {
694:             $this->userinfo = null;
695:         }
696:         else
697:         {
698:             $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
699:         }
700:         $this->valid[__FUNCTION__] = true;
701:         return true;
702:     }
703: 
704:     /**
705:      * Set the host. Returns true on success, false on failure (if there are
706:      * any invalid characters).
707:      *
708:      * @access public
709:      * @param string $host
710:      * @return bool
711:      */
712:     public function set_host($host)
713:     {
714:         if ($host === null || $host === '')
715:         {
716:             $this->host = null;
717:             $this->valid[__FUNCTION__] = true;
718:             return true;
719:         }
720:         elseif ($host[0] === '[' && substr($host, -1) === ']')
721:         {
722:             if (SimplePie_Net_IPv6::checkIPv6(substr($host, 1, -1)))
723:             {
724:                 $this->host = $host;
725:                 $this->valid[__FUNCTION__] = true;
726:                 return true;
727:             }
728:             else
729:             {
730:                 $this->host = null;
731:                 $this->valid[__FUNCTION__] = false;
732:                 return false;
733:             }
734:         }
735:         else
736:         {
737:             $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
738:             $this->valid[__FUNCTION__] = true;
739:             return true;
740:         }
741:     }
742: 
743:     /**
744:      * Set the port. Returns true on success, false on failure (if there are
745:      * any invalid characters).
746:      *
747:      * @access public
748:      * @param string $port
749:      * @return bool
750:      */
751:     public function set_port($port)
752:     {
753:         if ($port === null || $port === '')
754:         {
755:             $this->port = null;
756:             $this->valid[__FUNCTION__] = true;
757:             return true;
758:         }
759:         elseif (strspn($port, '0123456789') === strlen($port))
760:         {
761:             $this->port = (int) $port;
762:             $this->valid[__FUNCTION__] = true;
763:             return true;
764:         }
765:         else
766:         {
767:             $this->port = null;
768:             $this->valid[__FUNCTION__] = false;
769:             return false;
770:         }
771:     }
772: 
773:     /**
774:      * Set the path.
775:      *
776:      * @access public
777:      * @param string $path
778:      * @return bool
779:      */
780:     public function set_path($path)
781:     {
782:         if ($path === null || $path === '')
783:         {
784:             $this->path = null;
785:             $this->valid[__FUNCTION__] = true;
786:             return true;
787:         }
788:         elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
789:         {
790:             $this->path = null;
791:             $this->valid[__FUNCTION__] = false;
792:             return false;
793:         }
794:         else
795:         {
796:             $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
797:             if ($this->scheme !== null)
798:             {
799:                 $this->path = $this->remove_dot_segments($this->path);
800:             }
801:             $this->valid[__FUNCTION__] = true;
802:             return true;
803:         }
804:     }
805: 
806:     /**
807:      * Set the query.
808:      *
809:      * @access public
810:      * @param string $query
811:      * @return bool
812:      */
813:     public function set_query($query)
814:     {
815:         if ($query === null || $query === '')
816:         {
817:             $this->query = null;
818:         }
819:         else
820:         {
821:             $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?&=');
822:         }
823:         $this->valid[__FUNCTION__] = true;
824:         return true;
825:     }
826: 
827:     /**
828:      * Set the fragment.
829:      *
830:      * @access public
831:      * @param string $fragment
832:      * @return bool
833:      */
834:     public function set_fragment($fragment)
835:     {
836:         if ($fragment === null || $fragment === '')
837:         {
838:             $this->fragment = null;
839:         }
840:         else
841:         {
842:             $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
843:         }
844:         $this->valid[__FUNCTION__] = true;
845:         return true;
846:     }
847: 
848:     /**
849:      * Get the complete IRI
850:      *
851:      * @access public
852:      * @return string
853:      */
854:     public function get_iri()
855:     {
856:         $iri = '';
857:         if ($this->scheme !== null)
858:         {
859:             $iri .= $this->scheme . ':';
860:         }
861:         if (($authority = $this->get_authority()) !== null)
862:         {
863:             $iri .= '//' . $authority;
864:         }
865:         if ($this->path !== null)
866:         {
867:             $iri .= $this->path;
868:         }
869:         if ($this->query !== null)
870:         {
871:             $iri .= '?' . $this->query;
872:         }
873:         if ($this->fragment !== null)
874:         {
875:             $iri .= '#' . $this->fragment;
876:         }
877: 
878:         if ($iri !== '')
879:         {
880:             return $iri;
881:         }
882:         else
883:         {
884:             return null;
885:         }
886:     }
887: 
888:     /**
889:      * Get the scheme
890:      *
891:      * @access public
892:      * @return string
893:      */
894:     public function get_scheme()
895:     {
896:         return $this->scheme;
897:     }
898: 
899:     /**
900:      * Get the complete authority
901:      *
902:      * @access public
903:      * @return string
904:      */
905:     public function get_authority()
906:     {
907:         $authority = '';
908:         if ($this->userinfo !== null)
909:         {
910:             $authority .= $this->userinfo . '@';
911:         }
912:         if ($this->host !== null)
913:         {
914:             $authority .= $this->host;
915:         }
916:         if ($this->port !== null)
917:         {
918:             $authority .= ':' . $this->port;
919:         }
920: 
921:         if ($authority !== '')
922:         {
923:             return $authority;
924:         }
925:         else
926:         {
927:             return null;
928:         }
929:     }
930: 
931:     /**
932:      * Get the user information
933:      *
934:      * @access public
935:      * @return string
936:      */
937:     public function get_userinfo()
938:     {
939:         return $this->userinfo;
940:     }
941: 
942:     /**
943:      * Get the host
944:      *
945:      * @access public
946:      * @return string
947:      */
948:     public function get_host()
949:     {
950:         return $this->host;
951:     }
952: 
953:     /**
954:      * Get the port
955:      *
956:      * @access public
957:      * @return string
958:      */
959:     public function get_port()
960:     {
961:         return $this->port;
962:     }
963: 
964:     /**
965:      * Get the path
966:      *
967:      * @access public
968:      * @return string
969:      */
970:     public function get_path()
971:     {
972:         return $this->path;
973:     }
974: 
975:     /**
976:      * Get the query
977:      *
978:      * @access public
979:      * @return string
980:      */
981:     public function get_query()
982:     {
983:         return $this->query;
984:     }
985: 
986:     /**
987:      * Get the fragment
988:      *
989:      * @access public
990:      * @return string
991:      */
992:     public function get_fragment()
993:     {
994:         return $this->fragment;
995:     }
996: }
997: 
SimplePie Documentation API documentation generated by ApiGen 2.4.0