", $text);
+ }
+ return $text;
+ }
+
+ function mdwp_strip_p($t) { return preg_replace('{?p>}i', '', $t); }
+
+ function mdwp_hide_tags($text) {
+ global $mdwp_hidden_tags, $mdwp_placeholders;
+ return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text);
+ }
+ function mdwp_show_tags($text) {
+ global $mdwp_hidden_tags, $mdwp_placeholders;
+ return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text);
+ }
+}
+
+
+### bBlog Plugin Info ###
+
+function identify_modifier_markdown() {
+ return array(
+ 'name' => 'markdown',
+ 'type' => 'modifier',
+ 'nicename' => 'PHP Markdown Extra',
+ 'description' => 'A text-to-HTML conversion tool for web writers',
+ 'authors' => 'Michel Fortin and John Gruber',
+ 'licence' => 'GPL',
+ 'version' => MARKDOWNEXTRA_VERSION,
+ 'help' => 'Markdown syntax allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by John Gruber. More...',
+ );
+}
+
+
+### Smarty Modifier Interface ###
+
+function smarty_modifier_markdown($text) {
+ return Markdown($text);
+}
+
+
+### Textile Compatibility Mode ###
+
+# Rename this file to "classTextile.php" and it can replace Textile everywhere.
+
+if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) {
+ # Try to include PHP SmartyPants. Should be in the same directory.
+ @include_once 'smartypants.php';
+ # Fake Textile class. It calls Markdown instead.
+ class Textile {
+ function TextileThis($text, $lite='', $encode='') {
+ if ($lite == '' && $encode == '') $text = Markdown($text);
+ if (function_exists('SmartyPants')) $text = SmartyPants($text);
+ return $text;
+ }
+ # Fake restricted version: restrictions are not supported for now.
+ function TextileRestricted($text, $lite='', $noimage='') {
+ return $this->TextileThis($text, $lite);
+ }
+ # Workaround to ensure compatibility with TextPattern 4.0.3.
+ function blockLite($text) { return $text; }
+ }
+}
+
+
+
+#
+# Markdown Parser Class
+#
+
+class Markdown_Parser {
+
+ # Regex to match balanced [brackets].
+ # Needed to insert a maximum bracked depth while converting to PHP.
+ var $nested_brackets_depth = 6;
+ var $nested_brackets_re;
+
+ var $nested_url_parenthesis_depth = 4;
+ var $nested_url_parenthesis_re;
+
+ # Table of hash values for escaped characters:
+ var $escape_chars = '\`*_{}[]()>#+-.!';
+ var $escape_chars_re;
+
+ # Change to ">" for HTML output.
+ var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX;
+ var $tab_width = MARKDOWN_TAB_WIDTH;
+
+ # Change to `true` to disallow markup or entities.
+ var $no_markup = false;
+ var $no_entities = false;
+
+ # Predefined urls and titles for reference links and images.
+ var $predef_urls = array();
+ var $predef_titles = array();
+
+
+ function Markdown_Parser() {
+ #
+ # Constructor function. Initialize appropriate member variables.
+ #
+ $this->_initDetab();
+ $this->prepareItalicsAndBold();
+
+ $this->nested_brackets_re =
+ str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
+ str_repeat('\])*', $this->nested_brackets_depth);
+
+ $this->nested_url_parenthesis_re =
+ str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
+ str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
+
+ $this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
+
+ # Sort document, block, and span gamut in ascendent priority order.
+ asort($this->document_gamut);
+ asort($this->block_gamut);
+ asort($this->span_gamut);
+ }
+
+
+ # Internal hashes used during transformation.
+ var $urls = array();
+ var $titles = array();
+ var $html_hashes = array();
+
+ # Status flag to avoid invalid nesting.
+ var $in_anchor = false;
+
+
+ function setup() {
+ #
+ # Called before the transformation process starts to setup parser
+ # states.
+ #
+ # Clear global hashes.
+ $this->urls = $this->predef_urls;
+ $this->titles = $this->predef_titles;
+ $this->html_hashes = array();
+
+ $in_anchor = false;
+ }
+
+ function teardown() {
+ #
+ # Called after the transformation process to clear any variable
+ # which may be taking up memory unnecessarly.
+ #
+ $this->urls = array();
+ $this->titles = array();
+ $this->html_hashes = array();
+ }
+
+
+ function transform($text) {
+ #
+ # Main function. Performs some preprocessing on the input text
+ # and pass it through the document gamut.
+ #
+ $this->setup();
+
+ # Remove UTF-8 BOM and marker character in input, if present.
+ $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
+
+ # Standardize line endings:
+ # DOS to Unix and Mac to Unix
+ $text = preg_replace('{\r\n?}', "\n", $text);
+
+ # Make sure $text ends with a couple of newlines:
+ $text .= "\n\n";
+
+ # Convert all tabs to spaces.
+ $text = $this->detab($text);
+
+ # Turn block-level HTML blocks into hash entries
+ $text = $this->hashHTMLBlocks($text);
+
+ # Strip any lines consisting only of spaces and tabs.
+ # This makes subsequent regexen easier to write, because we can
+ # match consecutive blank lines with /\n+/ instead of something
+ # contorted like /[ ]*\n+/ .
+ $text = preg_replace('/^[ ]+$/m', '', $text);
+
+ # Run document gamut methods.
+ foreach ($this->document_gamut as $method => $priority) {
+ $text = $this->$method($text);
+ }
+
+ $this->teardown();
+
+ return $text . "\n";
+ }
+
+ var $document_gamut = array(
+ # Strip link definitions, store in hashes.
+ "stripLinkDefinitions" => 20,
+
+ "runBasicBlockGamut" => 30,
+ );
+
+
+ function stripLinkDefinitions($text) {
+ #
+ # Strips link definitions from text, stores the URLs and titles in
+ # hash references.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Link defs are in the form: ^[id]: url "optional title"
+ $text = preg_replace_callback('{
+ ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
+ [ ]*
+ \n? # maybe *one* newline
+ [ ]*
+ (\S+?)>? # url = $2
+ [ ]*
+ \n? # maybe one newline
+ [ ]*
+ (?:
+ (?<=\s) # lookbehind for whitespace
+ ["(]
+ (.*?) # title = $3
+ [")]
+ [ ]*
+ )? # title is optional
+ (?:\n+|\Z)
+ }xm',
+ array(&$this, '_stripLinkDefinitions_callback'),
+ $text);
+ return $text;
+ }
+ function _stripLinkDefinitions_callback($matches) {
+ $link_id = strtolower($matches[1]);
+ $this->urls[$link_id] = $matches[2];
+ $this->titles[$link_id] =& $matches[3];
+ return ''; # String that will replace the block
+ }
+
+
+ function hashHTMLBlocks($text) {
+ if ($this->no_markup) return $text;
+
+ $less_than_tab = $this->tab_width - 1;
+
+ # Hashify HTML blocks:
+ # We only want to do this for block-level HTML tags, such as headers,
+ # lists, and tables. That's because we still want to wrap
s around
+ # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+ # phrase emphasis, and spans. The list of tags we're looking for is
+ # hard-coded:
+ #
+ # * List "a" is made of tags which can be both inline or block-level.
+ # These will be treated block-level when the start tag is alone on
+ # its line, otherwise they're not matched here and will be taken as
+ # inline later.
+ # * List "b" is made of tags which are always block-level;
+ #
+ $block_tags_a_re = 'ins|del';
+ $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
+ 'script|noscript|form|fieldset|iframe|math';
+
+ # Regular expression for the content of a block tag.
+ $nested_tags_level = 4;
+ $attr = '
+ (?> # optional tag attributes
+ \s # starts with whitespace
+ (?>
+ [^>"/]+ # text outside quotes
+ |
+ /+(?!>) # slash not followed by ">"
+ |
+ "[^"]*" # text inside double quotes (tolerate ">")
+ |
+ \'[^\']*\' # text inside single quotes (tolerate ">")
+ )*
+ )?
+ ';
+ $content =
+ str_repeat('
+ (?>
+ [^<]+ # content without tag
+ |
+ <\2 # nested opening tag
+ '.$attr.' # attributes
+ (?>
+ />
+ |
+ >', $nested_tags_level). # end of opening tag
+ '.*?'. # last level nested tag content
+ str_repeat('
+ \2\s*> # closing nested tag
+ )
+ |
+ <(?!/\2\s*> # other tags with a different name
+ )
+ )*',
+ $nested_tags_level);
+ $content2 = str_replace('\2', '\3', $content);
+
+ # First, look for nested blocks, e.g.:
+ #
+ #
+ # tags for inner block must be indented.
+ #
+ #
+ #
+ # The outermost tags must start at the left margin for this to match, and
+ # the inner nested divs must be indented.
+ # We need to do this before the next, more liberal match, because the next
+ # match will start at the first `
` and stop at the first `
`.
+ $text = preg_replace_callback('{(?>
+ (?>
+ (?<=\n\n) # Starting after a blank line
+ | # or
+ \A\n? # the beginning of the doc
+ )
+ ( # save in $1
+
+ # Match from `\n` to `\n`, handling nested tags
+ # in between.
+
+ [ ]{0,'.$less_than_tab.'}
+ <('.$block_tags_b_re.')# start tag = $2
+ '.$attr.'> # attributes followed by > and \n
+ '.$content.' # content, support nesting
+ \2> # the matching end tag
+ [ ]* # trailing spaces/tabs
+ (?=\n+|\Z) # followed by a newline or end of document
+
+ | # Special version for tags of group a.
+
+ [ ]{0,'.$less_than_tab.'}
+ <('.$block_tags_a_re.')# start tag = $3
+ '.$attr.'>[ ]*\n # attributes followed by >
+ '.$content2.' # content, support nesting
+ \3> # the matching end tag
+ [ ]* # trailing spaces/tabs
+ (?=\n+|\Z) # followed by a newline or end of document
+
+ | # Special case just for . It was easier to make a special
+ # case than to make the other regex more complicated.
+
+ [ ]{0,'.$less_than_tab.'}
+ <(hr) # start tag = $2
+ '.$attr.' # attributes
+ /?> # the matching end tag
+ [ ]*
+ (?=\n{2,}|\Z) # followed by a blank line or end of document
+
+ | # Special case for standalone HTML comments:
+
+ [ ]{0,'.$less_than_tab.'}
+ (?s:
+
+ )
+ [ ]*
+ (?=\n{2,}|\Z) # followed by a blank line or end of document
+
+ | # PHP and ASP-style processor instructions ( and <%)
+
+ [ ]{0,'.$less_than_tab.'}
+ (?s:
+ <([?%]) # $2
+ .*?
+ \2>
+ )
+ [ ]*
+ (?=\n{2,}|\Z) # followed by a blank line or end of document
+
+ )
+ )}Sxmi',
+ array(&$this, '_hashHTMLBlocks_callback'),
+ $text);
+
+ return $text;
+ }
+ function _hashHTMLBlocks_callback($matches) {
+ $text = $matches[1];
+ $key = $this->hashBlock($text);
+ return "\n\n$key\n\n";
+ }
+
+
+ function hashPart($text, $boundary = 'X') {
+ #
+ # Called whenever a tag must be hashed when a function insert an atomic
+ # element in the text stream. Passing $text to through this function gives
+ # a unique text-token which will be reverted back when calling unhash.
+ #
+ # The $boundary argument specify what character should be used to surround
+ # the token. By convension, "B" is used for block elements that needs not
+ # to be wrapped into paragraph tags at the end, ":" is used for elements
+ # that are word separators and "X" is used in the general case.
+ #
+ # Swap back any tag hash found in $text so we do not have to `unhash`
+ # multiple times at the end.
+ $text = $this->unhash($text);
+
+ # Then hash the block.
+ static $i = 0;
+ $key = "$boundary\x1A" . ++$i . $boundary;
+ $this->html_hashes[$key] = $text;
+ return $key; # String that will replace the tag.
+ }
+
+
+ function hashBlock($text) {
+ #
+ # Shortcut function for hashPart with block-level boundaries.
+ #
+ return $this->hashPart($text, 'B');
+ }
+
+
+ var $block_gamut = array(
+ #
+ # These are all the transformations that form block-level
+ # tags like paragraphs, headers, and list items.
+ #
+ "doHeaders" => 10,
+ "doHorizontalRules" => 20,
+
+ "doLists" => 40,
+ "doCodeBlocks" => 50,
+ "doBlockQuotes" => 60,
+ );
+
+ function runBlockGamut($text) {
+ #
+ # Run block gamut tranformations.
+ #
+ # We need to escape raw HTML in Markdown source before doing anything
+ # else. This need to be done for each block, and not only at the
+ # begining in the Markdown function since hashed blocks can be part of
+ # list items and could have been indented. Indented blocks would have
+ # been seen as a code block in a previous pass of hashHTMLBlocks.
+ $text = $this->hashHTMLBlocks($text);
+
+ return $this->runBasicBlockGamut($text);
+ }
+
+ function runBasicBlockGamut($text) {
+ #
+ # Run block gamut tranformations, without hashing HTML blocks. This is
+ # useful when HTML blocks are known to be already hashed, like in the first
+ # whole-document pass.
+ #
+ foreach ($this->block_gamut as $method => $priority) {
+ $text = $this->$method($text);
+ }
+
+ # Finally form paragraph and restore hashed blocks.
+ $text = $this->formParagraphs($text);
+
+ return $text;
+ }
+
+
+ function doHorizontalRules($text) {
+ # Do Horizontal Rules:
+ return preg_replace(
+ '{
+ ^[ ]{0,3} # Leading space
+ ([-*_]) # $1: First marker
+ (?> # Repeated marker group
+ [ ]{0,2} # Zero, one, or two spaces.
+ \1 # Marker character
+ ){2,} # Group repeated at least twice
+ [ ]* # Tailing spaces
+ $ # End of line.
+ }mx',
+ "\n".$this->hashBlock("empty_element_suffix")."\n",
+ $text);
+ }
+
+
+ var $span_gamut = array(
+ #
+ # These are all the transformations that occur *within* block-level
+ # tags like paragraphs, headers, and list items.
+ #
+ # Process character escapes, code spans, and inline HTML
+ # in one shot.
+ "parseSpan" => -30,
+
+ # Process anchor and image tags. Images must come first,
+ # because ![foo][f] looks like an anchor.
+ "doImages" => 10,
+ "doAnchors" => 20,
+
+ # Make links out of things like ``
+ # Must come after doAnchors, because you can use < and >
+ # delimiters in inline links like [this]().
+ "doAutoLinks" => 30,
+ "encodeAmpsAndAngles" => 40,
+
+ "doItalicsAndBold" => 50,
+ "doHardBreaks" => 60,
+ );
+
+ function runSpanGamut($text) {
+ #
+ # Run span gamut tranformations.
+ #
+ foreach ($this->span_gamut as $method => $priority) {
+ $text = $this->$method($text);
+ }
+
+ return $text;
+ }
+
+
+ function doHardBreaks($text) {
+ # Do hard breaks:
+ return preg_replace_callback('/ {2,}\n/',
+ array(&$this, '_doHardBreaks_callback'), $text);
+ }
+ function _doHardBreaks_callback($matches) {
+ return $this->hashPart(" empty_element_suffix\n");
+ }
+
+
+ function doAnchors($text) {
+ #
+ # Turn Markdown link shortcuts into XHTML tags.
+ #
+ if ($this->in_anchor) return $text;
+ $this->in_anchor = true;
+
+ #
+ # First, handle reference-style links: [link text] [id]
+ #
+ $text = preg_replace_callback('{
+ ( # wrap whole match in $1
+ \[
+ ('.$this->nested_brackets_re.') # link text = $2
+ \]
+
+ [ ]? # one optional space
+ (?:\n[ ]*)? # one optional newline followed by spaces
+
+ \[
+ (.*?) # id = $3
+ \]
+ )
+ }xs',
+ array(&$this, '_doAnchors_reference_callback'), $text);
+
+ #
+ # Next, inline-style links: [link text](url "optional title")
+ #
+ $text = preg_replace_callback('{
+ ( # wrap whole match in $1
+ \[
+ ('.$this->nested_brackets_re.') # link text = $2
+ \]
+ \( # literal paren
+ [ ]*
+ (?:
+ <(\S*)> # href = $3
+ |
+ ('.$this->nested_url_parenthesis_re.') # href = $4
+ )
+ [ ]*
+ ( # $5
+ ([\'"]) # quote char = $6
+ (.*?) # Title = $7
+ \6 # matching quote
+ [ ]* # ignore any spaces/tabs between closing quote and )
+ )? # title is optional
+ \)
+ )
+ }xs',
+ array(&$this, '_DoAnchors_inline_callback'), $text);
+
+ #
+ # Last, handle reference-style shortcuts: [link text]
+ # These must come last in case you've also got [link test][1]
+ # or [link test](/foo)
+ #
+// $text = preg_replace_callback('{
+// ( # wrap whole match in $1
+// \[
+// ([^\[\]]+) # link text = $2; can\'t contain [ or ]
+// \]
+// )
+// }xs',
+// array(&$this, '_doAnchors_reference_callback'), $text);
+
+ $this->in_anchor = false;
+ return $text;
+ }
+ function _doAnchors_reference_callback($matches) {
+ $whole_match = $matches[1];
+ $link_text = $matches[2];
+ $link_id =& $matches[3];
+
+ if ($link_id == "") {
+ # for shortcut links like [this][] or [this].
+ $link_id = $link_text;
+ }
+
+ # lower-case and turn embedded newlines into spaces
+ $link_id = strtolower($link_id);
+ $link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
+
+ if (isset($this->urls[$link_id])) {
+ $url = $this->urls[$link_id];
+ $url = $this->encodeAttribute($url);
+
+ $result = "titles[$link_id] ) ) {
+ $title = $this->titles[$link_id];
+ $title = $this->encodeAttribute($title);
+ $result .= " title=\"$title\"";
+ }
+
+ $link_text = $this->runSpanGamut($link_text);
+ $result .= ">$link_text";
+ $result = $this->hashPart($result);
+ }
+ else {
+ $result = $whole_match;
+ }
+ return $result;
+ }
+ function _doAnchors_inline_callback($matches) {
+ $whole_match = $matches[1];
+ $link_text = $this->runSpanGamut($matches[2]);
+ $url = $matches[3] == '' ? $matches[4] : $matches[3];
+ $title =& $matches[7];
+
+ $url = $this->encodeAttribute($url);
+
+ $result = "encodeAttribute($title);
+ $result .= " title=\"$title\"";
+ }
+
+ $link_text = $this->runSpanGamut($link_text);
+ $result .= ">$link_text";
+
+ return $this->hashPart($result);
+ }
+
+
+ function doImages($text) {
+ #
+ # Turn Markdown image shortcuts into tags.
+ #
+ #
+ # First, handle reference-style labeled images: ![alt text][id]
+ #
+ $text = preg_replace_callback('{
+ ( # wrap whole match in $1
+ !\[
+ ('.$this->nested_brackets_re.') # alt text = $2
+ \]
+
+ [ ]? # one optional space
+ (?:\n[ ]*)? # one optional newline followed by spaces
+
+ \[
+ (.*?) # id = $3
+ \]
+
+ )
+ }xs',
+ array(&$this, '_doImages_reference_callback'), $text);
+
+ #
+ # Next, handle inline images: 
+ # Don't forget: encode * and _
+ #
+ $text = preg_replace_callback('{
+ ( # wrap whole match in $1
+ !\[
+ ('.$this->nested_brackets_re.') # alt text = $2
+ \]
+ \s? # One optional whitespace character
+ \( # literal paren
+ [ ]*
+ (?:
+ <(\S*)> # src url = $3
+ |
+ ('.$this->nested_url_parenthesis_re.') # src url = $4
+ )
+ [ ]*
+ ( # $5
+ ([\'"]) # quote char = $6
+ (.*?) # title = $7
+ \6 # matching quote
+ [ ]*
+ )? # title is optional
+ \)
+ )
+ }xs',
+ array(&$this, '_doImages_inline_callback'), $text);
+
+ return $text;
+ }
+ function _doImages_reference_callback($matches) {
+ $whole_match = $matches[1];
+ $alt_text = $matches[2];
+ $link_id = strtolower($matches[3]);
+
+ if ($link_id == "") {
+ $link_id = strtolower($alt_text); # for shortcut links like ![this][].
+ }
+
+ $alt_text = $this->encodeAttribute($alt_text);
+ if (isset($this->urls[$link_id])) {
+ $url = $this->encodeAttribute($this->urls[$link_id]);
+ $result = "titles[$link_id])) {
+ $title = $this->titles[$link_id];
+ $title = $this->encodeAttribute($title);
+ $result .= " title=\"$title\"";
+ }
+ $result .= $this->empty_element_suffix;
+ $result = $this->hashPart($result);
+ }
+ else {
+ # If there's no such link ID, leave intact:
+ $result = $whole_match;
+ }
+
+ return $result;
+ }
+ function _doImages_inline_callback($matches) {
+ $whole_match = $matches[1];
+ $alt_text = $matches[2];
+ $url = $matches[3] == '' ? $matches[4] : $matches[3];
+ $title =& $matches[7];
+
+ $alt_text = $this->encodeAttribute($alt_text);
+ $url = $this->encodeAttribute($url);
+ $result = "encodeAttribute($title);
+ $result .= " title=\"$title\""; # $title already quoted
+ }
+ $result .= $this->empty_element_suffix;
+
+ return $this->hashPart($result);
+ }
+
+
+ function doHeaders($text) {
+ # Setext-style headers:
+ # Header 1
+ # ========
+ #
+ # Header 2
+ # --------
+ #
+ $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
+ array(&$this, '_doHeaders_callback_setext'), $text);
+
+ # atx-style headers:
+ # # Header 1
+ # ## Header 2
+ # ## Header 2 with closing hashes ##
+ # ...
+ # ###### Header 6
+ #
+ $text = preg_replace_callback('{
+ ^(\#{1,6}) # $1 = string of #\'s
+ [ ]*
+ (.+?) # $2 = Header text
+ [ ]*
+ \#* # optional closing #\'s (not counted)
+ \n+
+ }xm',
+ array(&$this, '_doHeaders_callback_atx'), $text);
+
+ return $text;
+ }
+ function _doHeaders_callback_setext($matches) {
+ # Terrible hack to check we haven't found an empty list item.
+ if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
+ return $matches[0];
+
+ $level = $matches[2]{0} == '=' ? 1 : 2;
+ $block = "".$this->runSpanGamut($matches[1])."";
+ return "\n" . $this->hashBlock($block) . "\n\n";
+ }
+ function _doHeaders_callback_atx($matches) {
+ $level = strlen($matches[1]);
+ $block = "".$this->runSpanGamut($matches[2])."";
+ return "\n" . $this->hashBlock($block) . "\n\n";
+ }
+
+
+ function doLists($text) {
+ #
+ # Form HTML ordered (numbered) and unordered (bulleted) lists.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Re-usable patterns to match list item bullets and number markers:
+ $marker_ul_re = '[*+-]';
+ $marker_ol_re = '\d+[.]';
+ $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+ $markers_relist = array($marker_ul_re, $marker_ol_re);
+
+ foreach ($markers_relist as $marker_re) {
+ # Re-usable pattern to match any entirel ul or ol list:
+ $whole_list_re = '
+ ( # $1 = whole list
+ ( # $2
+ [ ]{0,'.$less_than_tab.'}
+ ('.$marker_re.') # $3 = first list item marker
+ [ ]+
+ )
+ (?s:.+?)
+ ( # $4
+ \z
+ |
+ \n{2,}
+ (?=\S)
+ (?! # Negative lookahead for another list item marker
+ [ ]*
+ '.$marker_re.'[ ]+
+ )
+ )
+ )
+ '; // mx
+
+ # We use a different prefix before nested lists than top-level lists.
+ # See extended comment in _ProcessListItems().
+
+ if ($this->list_level) {
+ $text = preg_replace_callback('{
+ ^
+ '.$whole_list_re.'
+ }mx',
+ array(&$this, '_doLists_callback'), $text);
+ }
+ else {
+ $text = preg_replace_callback('{
+ (?:(?<=\n)\n|\A\n?) # Must eat the newline
+ '.$whole_list_re.'
+ }mx',
+ array(&$this, '_doLists_callback'), $text);
+ }
+ }
+
+ return $text;
+ }
+ function _doLists_callback($matches) {
+ # Re-usable patterns to match list item bullets and number markers:
+ $marker_ul_re = '[*+-]';
+ $marker_ol_re = '\d+[.]';
+ $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+ $list = $matches[1];
+ $list_type = preg_match("/$marker_ul_re/", $matches[3]) ? "ul" : "ol";
+
+ $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
+
+ $list .= "\n";
+ $result = $this->processListItems($list, $marker_any_re);
+
+ $result = $this->hashBlock("<$list_type>\n" . $result . "$list_type>");
+ return "\n". $result ."\n\n";
+ }
+
+ var $list_level = 0;
+
+ function processListItems($list_str, $marker_any_re) {
+ #
+ # Process the contents of a single ordered or unordered list, splitting it
+ # into individual list items.
+ #
+ # The $this->list_level global keeps track of when we're inside a list.
+ # Each time we enter a list, we increment it; when we leave a list,
+ # we decrement. If it's zero, we're not in a list anymore.
+ #
+ # We do this because when we're not inside a list, we want to treat
+ # something like this:
+ #
+ # I recommend upgrading to version
+ # 8. Oops, now this line is treated
+ # as a sub-list.
+ #
+ # As a single paragraph, despite the fact that the second line starts
+ # with a digit-period-space sequence.
+ #
+ # Whereas when we're inside a list (or sub-list), that line will be
+ # treated as the start of a sub-list. What a kludge, huh? This is
+ # an aspect of Markdown's syntax that's hard to parse perfectly
+ # without resorting to mind-reading. Perhaps the solution is to
+ # change the syntax rules such that sub-lists must start with a
+ # starting cardinal number; e.g. "1." or "a.".
+
+ $this->list_level++;
+
+ # trim trailing blank lines:
+ $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+ $list_str = preg_replace_callback('{
+ (\n)? # leading line = $1
+ (^[ ]*) # leading whitespace = $2
+ ('.$marker_any_re.' # list marker and space = $3
+ (?:[ ]+|(?=\n)) # space only required if item is not empty
+ )
+ ((?s:.*?)) # list item text = $4
+ (?:(\n+(?=\n))|\n) # tailing blank line = $5
+ (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
+ }xm',
+ array(&$this, '_processListItems_callback'), $list_str);
+
+ $this->list_level--;
+ return $list_str;
+ }
+ function _processListItems_callback($matches) {
+ $item = $matches[4];
+ $leading_line =& $matches[1];
+ $leading_space =& $matches[2];
+ $marker_space = $matches[3];
+ $tailing_blank_line =& $matches[5];
+
+ if ($leading_line || $tailing_blank_line ||
+ preg_match('/\n{2,}/', $item))
+ {
+ # Replace marker with the appropriate whitespace indentation
+ $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
+ $item = $this->runBlockGamut($this->outdent($item)."\n");
+ }
+ else {
+ # Recursion for sub-lists:
+ $item = $this->doLists($this->outdent($item));
+ $item = preg_replace('/\n+$/', '', $item);
+ $item = $this->runSpanGamut($item);
+ }
+
+ return "
" . $item . "
\n";
+ }
+
+
+ function doCodeBlocks($text) {
+ #
+ # Process Markdown `
` blocks.
+ #
+ $text = preg_replace_callback('{
+ (?:\n\n|\A\n?)
+ ( # $1 = the code block -- one or more lines, starting with a space/tab
+ (?>
+ [ ]{'.$this->tab_width.'} # Lines must start with a tab or a tab-width of spaces
+ .*\n+
+ )+
+ )
+ ((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
+ }xm',
+ array(&$this, '_doCodeBlocks_callback'), $text);
+
+ return $text;
+ }
+ function _doCodeBlocks_callback($matches) {
+ $codeblock = $matches[1];
+
+ $codeblock = $this->outdent($codeblock);
+ $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+
+ # trim leading newlines and trailing newlines
+ $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
+
+ $codeblock = "
$codeblock\n
";
+ return "\n\n".$this->hashBlock($codeblock)."\n\n";
+ }
+
+
+ function makeCodeSpan($code) {
+ #
+ # Create a code span markup for $code. Called from handleSpanToken.
+ #
+ $code = htmlspecialchars(trim($code), ENT_NOQUOTES);
+ return $this->hashPart("$code");
+ }
+
+
+ var $em_relist = array(
+ '' => '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(?em_relist as $em => $em_re) {
+ foreach ($this->strong_relist as $strong => $strong_re) {
+ # Construct list of allowed token expressions.
+ $token_relist = array();
+ if (isset($this->em_strong_relist["$em$strong"])) {
+ $token_relist[] = $this->em_strong_relist["$em$strong"];
+ }
+ $token_relist[] = $em_re;
+ $token_relist[] = $strong_re;
+
+ # Construct master expression from list.
+ $token_re = '{('. implode('|', $token_relist) .')}';
+ $this->em_strong_prepared_relist["$em$strong"] = $token_re;
+ }
+ }
+ }
+
+ function doItalicsAndBold($text) {
+ $token_stack = array('');
+ $text_stack = array('');
+ $em = '';
+ $strong = '';
+ $tree_char_em = false;
+
+ while (1) {
+ #
+ # Get prepared regular expression for seraching emphasis tokens
+ # in current context.
+ #
+ $token_re = $this->em_strong_prepared_relist["$em$strong"];
+
+ #
+ # Each loop iteration seach for the next emphasis token.
+ # Each token is then passed to handleSpanToken.
+ #
+ $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $text_stack[0] .= $parts[0];
+ $token =& $parts[1];
+ $text =& $parts[2];
+
+ if (empty($token)) {
+ # Reached end of text span: empty stack without emitting.
+ # any more emphasis.
+ while ($token_stack[0]) {
+ $text_stack[1] .= array_shift($token_stack);
+ $text_stack[0] .= array_shift($text_stack);
+ }
+ break;
+ }
+
+ $token_len = strlen($token);
+ if ($tree_char_em) {
+ # Reached closing marker while inside a three-char emphasis.
+ if ($token_len == 3) {
+ # Three-char closing marker, close em and strong.
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "$span";
+ $text_stack[0] .= $this->hashPart($span);
+ $em = '';
+ $strong = '';
+ } else {
+ # Other closing marker: close one em or strong and
+ # change current token state to match the other
+ $token_stack[0] = str_repeat($token{0}, 3-$token_len);
+ $tag = $token_len == 2 ? "strong" : "em";
+ $span = $text_stack[0];
+ $span = $this->runSpanGamut($span);
+ $span = "<$tag>$span$tag>";
+ $text_stack[0] = $this->hashPart($span);
+ $$tag = ''; # $$tag stands for $em or $strong
+ }
+ $tree_char_em = false;
+ } else if ($token_len == 3) {
+ if ($em) {
+ # Reached closing marker for both em and strong.
+ # Closing strong marker:
+ for ($i = 0; $i < 2; ++$i) {
+ $shifted_token = array_shift($token_stack);
+ $tag = strlen($shifted_token) == 2 ? "strong" : "em";
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "<$tag>$span$tag>";
+ $text_stack[0] .= $this->hashPart($span);
+ $$tag = ''; # $$tag stands for $em or $strong
+ }
+ } else {
+ # Reached opening three-char emphasis marker. Push on token
+ # stack; will be handled by the special condition above.
+ $em = $token{0};
+ $strong = "$em$em";
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $tree_char_em = true;
+ }
+ } else if ($token_len == 2) {
+ if ($strong) {
+ # Unwind any dangling emphasis marker:
+ if (strlen($token_stack[0]) == 1) {
+ $text_stack[1] .= array_shift($token_stack);
+ $text_stack[0] .= array_shift($text_stack);
+ }
+ # Closing strong marker:
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "$span";
+ $text_stack[0] .= $this->hashPart($span);
+ $strong = '';
+ } else {
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $strong = $token;
+ }
+ } else {
+ # Here $token_len == 1
+ if ($em) {
+ if (strlen($token_stack[0]) == 1) {
+ # Closing emphasis marker:
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "$span";
+ $text_stack[0] .= $this->hashPart($span);
+ $em = '';
+ } else {
+ $text_stack[0] .= $token;
+ }
+ } else {
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $em = $token;
+ }
+ }
+ }
+ return $text_stack[0];
+ }
+
+
+ function doBlockQuotes($text) {
+ $text = preg_replace_callback('/
+ ( # Wrap whole match in $1
+ (?>
+ ^[ ]*>[ ]? # ">" at the start of a line
+ .+\n # rest of the first line
+ (.+\n)* # subsequent consecutive lines
+ \n* # blanks
+ )+
+ )
+ /xm',
+ array(&$this, '_doBlockQuotes_callback'), $text);
+
+ return $text;
+ }
+ function _doBlockQuotes_callback($matches) {
+ $bq = $matches[1];
+ # trim one level of quoting - trim whitespace-only lines
+ $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
+ $bq = $this->runBlockGamut($bq); # recurse
+
+ $bq = preg_replace('/^/m', " ", $bq);
+ # These leading spaces cause problem with
content,
+ # so we need to fix that:
+ $bq = preg_replace_callback('{(\s*
+ #
+ # Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
+ # With some optimizations by Milian Wolff.
+ #
+ $addr = "mailto:" . $addr;
+ $chars = preg_split('/(? $char) {
+ $ord = ord($char);
+ # Ignore non-ascii chars.
+ if ($ord < 128) {
+ $r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
+ # roughly 10% raw, 45% hex, 45% dec
+ # '@' *must* be encoded. I insist.
+ if ($r > 90 && $char != '@') /* do nothing */;
+ else if ($r < 45) $chars[$key] = ''.dechex($ord).';';
+ else $chars[$key] = ''.$ord.';';
+ }
+ }
+
+ $addr = implode('', $chars);
+ $text = implode('', array_slice($chars, 7)); # text without `mailto:`
+ $addr = "$text";
+
+ return $addr;
+ }
+
+
+ function parseSpan($str) {
+ #
+ # Take the string $str and parse it into tokens, hashing embeded HTML,
+ # escaped characters and handling code spans.
+ #
+ $output = '';
+
+ $span_re = '{
+ (
+ \\\\'.$this->escape_chars_re.'
+ |
+ (?no_markup ? '' : '
+ |
+ # comment
+ |
+ <\?.*?\?> | <%.*?%> # processing instruction
+ |
+ <[/!$]?[-a-zA-Z0-9:]+ # regular tags
+ (?>
+ \s
+ (?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
+ )?
+ >
+ ').'
+ )
+ }xs';
+
+ while (1) {
+ #
+ # Each loop iteration seach for either the next tag, the next
+ # openning code span marker, or the next escaped character.
+ # Each token is then passed to handleSpanToken.
+ #
+ $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
+
+ # Create token from text preceding tag.
+ if ($parts[0] != "") {
+ $output .= $parts[0];
+ }
+
+ # Check if we reach the end.
+ if (isset($parts[1])) {
+ $output .= $this->handleSpanToken($parts[1], $parts[2]);
+ $str = $parts[2];
+ }
+ else {
+ break;
+ }
+ }
+
+ return $output;
+ }
+
+
+ function handleSpanToken($token, &$str) {
+ #
+ # Handle $token provided by parseSpan by determining its nature and
+ # returning the corresponding value that should replace it.
+ #
+ switch ($token{0}) {
+ case "\\":
+ return $this->hashPart("". ord($token{1}). ";");
+ case "`":
+ # Search for end marker in remaining text.
+ if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
+ $str, $matches))
+ {
+ $str = $matches[2];
+ $codespan = $this->makeCodeSpan($matches[1]);
+ return $this->hashPart($codespan);
+ }
+ return $token; // return as text since no ending marker found.
+ default:
+ return $this->hashPart($token);
+ }
+ }
+
+
+ function outdent($text) {
+ #
+ # Remove one level of line-leading tabs or spaces
+ #
+ return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
+ }
+
+
+ # String length function for detab. `_initDetab` will create a function to
+ # hanlde UTF-8 if the default function does not exist.
+ var $utf8_strlen = 'mb_strlen';
+
+ function detab($text) {
+ #
+ # Replace tabs with the appropriate amount of space.
+ #
+ # For each line we separate the line in blocks delemited by
+ # tab characters. Then we reconstruct every line by adding the
+ # appropriate number of space between each blocks.
+
+ $text = preg_replace_callback('/^.*\t.*$/m',
+ array(&$this, '_detab_callback'), $text);
+
+ return $text;
+ }
+ function _detab_callback($matches) {
+ $line = $matches[0];
+ $strlen = $this->utf8_strlen; # strlen function for UTF-8.
+
+ # Split in blocks.
+ $blocks = explode("\t", $line);
+ # Add each blocks to the line.
+ $line = $blocks[0];
+ unset($blocks[0]); # Do not add first block twice.
+ foreach ($blocks as $block) {
+ # Calculate amount of space, insert spaces, insert block.
+ $amount = $this->tab_width -
+ $strlen($line, 'UTF-8') % $this->tab_width;
+ $line .= str_repeat(" ", $amount) . $block;
+ }
+ return $line;
+ }
+ function _initDetab() {
+ #
+ # Check for the availability of the function in the `utf8_strlen` property
+ # (initially `mb_strlen`). If the function is not available, create a
+ # function that will loosely count the number of UTF-8 characters with a
+ # regular expression.
+ #
+ if (function_exists($this->utf8_strlen)) return;
+ $this->utf8_strlen = create_function('$text', 'return preg_match_all(
+ "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
+ $text, $m);');
+ }
+
+
+ function unhash($text) {
+ #
+ # Swap back in all the tags hashed by _HashHTMLBlocks.
+ #
+ return preg_replace_callback('/(.)\x1A[0-9]+\1/',
+ array(&$this, '_unhash_callback'), $text);
+ }
+ function _unhash_callback($matches) {
+ return $this->html_hashes[$matches[0]];
+ }
+
+}
+
+
+#
+# Markdown Extra Parser Class
+#
+
+class MarkdownExtra_Parser extends Markdown_Parser {
+
+ # Prefix for footnote ids.
+ var $fn_id_prefix = "";
+
+ # Optional title attribute for footnote links and backlinks.
+ var $fn_link_title = MARKDOWN_FN_LINK_TITLE;
+ var $fn_backlink_title = MARKDOWN_FN_BACKLINK_TITLE;
+
+ # Optional class attribute for footnote links and backlinks.
+ var $fn_link_class = MARKDOWN_FN_LINK_CLASS;
+ var $fn_backlink_class = MARKDOWN_FN_BACKLINK_CLASS;
+
+ # Predefined abbreviations.
+ var $predef_abbr = array();
+
+
+ function MarkdownExtra_Parser() {
+ #
+ # Constructor function. Initialize the parser object.
+ #
+ # Add extra escapable characters before parent constructor
+ # initialize the table.
+ $this->escape_chars .= ':|';
+
+ # Insert extra document, block, and span transformations.
+ # Parent constructor will do the sorting.
+ $this->document_gamut += array(
+ "doFencedCodeBlocks" => 5,
+ "stripFootnotes" => 15,
+ "stripAbbreviations" => 25,
+ "appendFootnotes" => 50,
+ );
+ $this->block_gamut += array(
+ "doFencedCodeBlocks" => 5,
+ "doTables" => 15,
+ "doDefLists" => 45,
+ );
+ $this->span_gamut += array(
+ "doFootnotes" => 5,
+ "doAbbreviations" => 70,
+ );
+
+ parent::Markdown_Parser();
+ }
+
+
+ # Extra variables used during extra transformations.
+ var $footnotes = array();
+ var $footnotes_ordered = array();
+ var $abbr_desciptions = array();
+ var $abbr_word_re = '';
+
+ # Give the current footnote number.
+ var $footnote_counter = 1;
+
+
+ function setup() {
+ #
+ # Setting up Extra-specific variables.
+ #
+ parent::setup();
+
+ $this->footnotes = array();
+ $this->footnotes_ordered = array();
+ $this->abbr_desciptions = array();
+ $this->abbr_word_re = '';
+ $this->footnote_counter = 1;
+
+ foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
+ if ($this->abbr_word_re)
+ $this->abbr_word_re .= '|';
+ $this->abbr_word_re .= preg_quote($abbr_word);
+ $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+ }
+ }
+
+ function teardown() {
+ #
+ # Clearing Extra-specific variables.
+ #
+ $this->footnotes = array();
+ $this->footnotes_ordered = array();
+ $this->abbr_desciptions = array();
+ $this->abbr_word_re = '';
+
+ parent::teardown();
+ }
+
+
+ ### HTML Block Parser ###
+
+ # Tags that are always treated as block tags:
+ var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend';
+
+ # Tags treated as block tags only if the opening tag is alone on it's line:
+ var $context_block_tags_re = 'script|noscript|math|ins|del';
+
+ # Tags where markdown="1" default to span mode:
+ var $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
+
+ # Tags which must not have their contents modified, no matter where
+ # they appear:
+ var $clean_tags_re = 'script|math';
+
+ # Tags that do not need to be closed.
+ var $auto_close_tags_re = 'hr|img';
+
+
+ function hashHTMLBlocks($text) {
+ #
+ # Hashify HTML Blocks and "clean tags".
+ #
+ # We only want to do this for block-level HTML tags, such as headers,
+ # lists, and tables. That's because we still want to wrap
s around
+ # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+ # phrase emphasis, and spans. The list of tags we're looking for is
+ # hard-coded.
+ #
+ # This works by calling _HashHTMLBlocks_InMarkdown, which then calls
+ # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1"
+ # attribute is found whitin a tag, _HashHTMLBlocks_InHTML calls back
+ # _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag.
+ # These two functions are calling each other. It's recursive!
+ #
+ #
+ # Call the HTML-in-Markdown hasher.
+ #
+ list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text);
+
+ return $text;
+ }
+ function _hashHTMLBlocks_inMarkdown($text, $indent = 0,
+ $enclosing_tag_re = '', $span = false)
+ {
+ #
+ # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags.
+ #
+ # * $indent is the number of space to be ignored when checking for code
+ # blocks. This is important because if we don't take the indent into
+ # account, something like this (which looks right) won't work as expected:
+ #
+ #
+ #
+ # Hello World. <-- Is this a Markdown code block or text?
+ #
<-- Is this a Markdown code block or a real tag?
+ #
+ #
+ # If you don't like this, just don't indent the tag on which
+ # you apply the markdown="1" attribute.
+ #
+ # * If $enclosing_tag_re is not empty, stops at the first unmatched closing
+ # tag with that name. Nested tags supported.
+ #
+ # * If $span is true, text inside must treated as span. So any double
+ # newline will be replaced by a single newline so that it does not create
+ # paragraphs.
+ #
+ # Returns an array of that form: ( processed text , remaining text )
+ #
+ if ($text === '') return array('', '');
+
+ # Regex to check for the presense of newlines around a block tag.
+ $newline_before_re = '/(?:^\n?|\n\n)*$/';
+ $newline_after_re =
+ '{
+ ^ # Start of text following the tag.
+ (?>[ ]*)? # Optional comment.
+ [ ]*\n # Must be followed by newline.
+ }xs';
+
+ # Regex to match any tag.
+ $block_tag_re =
+ '{
+ ( # $2: Capture hole tag.
+ ? # Any opening or closing tag.
+ (?> # Tag name.
+ '.$this->block_tags_re.' |
+ '.$this->context_block_tags_re.' |
+ '.$this->clean_tags_re.' |
+ (?!\s)'.$enclosing_tag_re.'
+ )
+ (?:
+ (?=[\s"\'/]) # Allowed characters after tag name.
+ (?>
+ ".*?" | # Double quotes (can contain `>`)
+ \'.*?\' | # Single quotes (can contain `>`)
+ .+? # Anything but quotes and `>`.
+ )*?
+ )?
+ > # End of tag.
+ |
+ # HTML Comment
+ |
+ <\?.*?\?> | <%.*?%> # Processing instruction
+ |
+ # CData Block
+ |
+ # Code span marker
+ `+
+ '. ( !$span ? ' # If not in span.
+ |
+ # Indented code block
+ (?> ^[ ]*\n? | \n[ ]*\n )
+ [ ]{'.($indent+4).'}[^\n]* \n
+ (?>
+ (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n
+ )*
+ |
+ # Fenced code block marker
+ (?> ^ | \n )
+ [ ]{'.($indent).'}~~~+[ ]*\n
+ ' : '' ). ' # End (if not is span).
+ )
+ }xs';
+
+
+ $depth = 0; # Current depth inside the tag tree.
+ $parsed = ""; # Parsed text that will be returned.
+
+ #
+ # Loop through every tag until we find the closing tag of the parent
+ # or loop until reaching the end of text if no parent tag specified.
+ #
+ do {
+ #
+ # Split the text using the first $tag_match pattern found.
+ # Text before pattern will be first in the array, text after
+ # pattern will be at the end, and between will be any catches made
+ # by the pattern.
+ #
+ $parts = preg_split($block_tag_re, $text, 2,
+ PREG_SPLIT_DELIM_CAPTURE);
+
+ # If in Markdown span mode, add a empty-string span-level hash
+ # after each newline to prevent triggering any block element.
+ if ($span) {
+ $void = $this->hashPart("", ':');
+ $newline = "$void\n";
+ $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void;
+ }
+
+ $parsed .= $parts[0]; # Text before current tag.
+
+ # If end of $text has been reached. Stop loop.
+ if (count($parts) < 3) {
+ $text = "";
+ break;
+ }
+
+ $tag = $parts[1]; # Tag to handle.
+ $text = $parts[2]; # Remaining text after current tag.
+ $tag_re = preg_quote($tag); # For use in a regular expression.
+
+ #
+ # Check for: Code span marker
+ #
+ if ($tag{0} == "`") {
+ # Find corresponding end marker.
+ $tag_re = preg_quote($tag);
+ if (preg_match('{^(?>.+?|\n(?!\n))*?(?.*\n)+?'.$tag_re.' *\n}', $text,
+ $matches))
+ {
+ # End marker found: pass text unchanged until marker.
+ $parsed .= $tag . $matches[0];
+ $text = substr($text, strlen($matches[0]));
+ }
+ else {
+ # No end marker: just skip it.
+ $parsed .= $tag;
+ }
+ }
+ }
+ #
+ # Check for: Opening Block level tag or
+ # Opening Context Block tag (like ins and del)
+ # used as a block tag (tag is alone on it's line).
+ #
+ else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) ||
+ ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) &&
+ preg_match($newline_before_re, $parsed) &&
+ preg_match($newline_after_re, $text) )
+ )
+ {
+ # Need to parse tag and following text using the HTML parser.
+ list($block_text, $text) =
+ $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true);
+
+ # Make sure it stays outside of any paragraph by adding newlines.
+ $parsed .= "\n\n$block_text\n\n";
+ }
+ #
+ # Check for: Clean tag (like script, math)
+ # HTML Comments, processing instructions.
+ #
+ else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) ||
+ $tag{1} == '!' || $tag{1} == '?')
+ {
+ # Need to parse tag and following text using the HTML parser.
+ # (don't check for markdown attribute)
+ list($block_text, $text) =
+ $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false);
+
+ $parsed .= $block_text;
+ }
+ #
+ # Check for: Tag with same name as enclosing tag.
+ #
+ else if ($enclosing_tag_re !== '' &&
+ # Same name as enclosing tag.
+ preg_match('{^?(?:'.$enclosing_tag_re.')\b}', $tag))
+ {
+ #
+ # Increase/decrease nested tag count.
+ #
+ if ($tag{1} == '/') $depth--;
+ else if ($tag{strlen($tag)-2} != '/') $depth++;
+
+ if ($depth < 0) {
+ #
+ # Going out of parent element. Clean up and break so we
+ # return to the calling function.
+ #
+ $text = $tag . $text;
+ break;
+ }
+
+ $parsed .= $tag;
+ }
+ else {
+ $parsed .= $tag;
+ }
+ } while ($depth >= 0);
+
+ return array($parsed, $text);
+ }
+ function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
+ #
+ # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags.
+ #
+ # * Calls $hash_method to convert any blocks.
+ # * Stops when the first opening tag closes.
+ # * $md_attr indicate if the use of the `markdown="1"` attribute is allowed.
+ # (it is not inside clean tags)
+ #
+ # Returns an array of that form: ( processed text , remaining text )
+ #
+ if ($text === '') return array('', '');
+
+ # Regex to match `markdown` attribute inside of a tag.
+ $markdown_attr_re = '
+ {
+ \s* # Eat whitespace before the `markdown` attribute
+ markdown
+ \s*=\s*
+ (?>
+ (["\']) # $1: quote delimiter
+ (.*?) # $2: attribute value
+ \1 # matching delimiter
+ |
+ ([^\s>]*) # $3: unquoted attribute value
+ )
+ () # $4: make $3 always defined (avoid warnings)
+ }xs';
+
+ # Regex to match any tag.
+ $tag_re = '{
+ ( # $2: Capture hole tag.
+ ? # Any opening or closing tag.
+ [\w:$]+ # Tag name.
+ (?:
+ (?=[\s"\'/]) # Allowed characters after tag name.
+ (?>
+ ".*?" | # Double quotes (can contain `>`)
+ \'.*?\' | # Single quotes (can contain `>`)
+ .+? # Anything but quotes and `>`.
+ )*?
+ )?
+ > # End of tag.
+ |
+ # HTML Comment
+ |
+ <\?.*?\?> | <%.*?%> # Processing instruction
+ |
+ # CData Block
+ )
+ }xs';
+
+ $original_text = $text; # Save original text in case of faliure.
+
+ $depth = 0; # Current depth inside the tag tree.
+ $block_text = ""; # Temporary text holder for current text.
+ $parsed = ""; # Parsed text that will be returned.
+
+ #
+ # Get the name of the starting tag.
+ # (This pattern makes $base_tag_name_re safe without quoting.)
+ #
+ if (preg_match('/^<([\w:$]*)\b/', $text, $matches))
+ $base_tag_name_re = $matches[1];
+
+ #
+ # Loop through every tag until we find the corresponding closing tag.
+ #
+ do {
+ #
+ # Split the text using the first $tag_match pattern found.
+ # Text before pattern will be first in the array, text after
+ # pattern will be at the end, and between will be any catches made
+ # by the pattern.
+ #
+ $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+
+ if (count($parts) < 3) {
+ #
+ # End of $text reached with unbalenced tag(s).
+ # In that case, we return original text unchanged and pass the
+ # first character as filtered to prevent an infinite loop in the
+ # parent function.
+ #
+ return array($original_text{0}, substr($original_text, 1));
+ }
+
+ $block_text .= $parts[0]; # Text before current tag.
+ $tag = $parts[1]; # Tag to handle.
+ $text = $parts[2]; # Remaining text after current tag.
+
+ #
+ # Check for: Auto-close tag (like )
+ # Comments and Processing Instructions.
+ #
+ if (preg_match('{^?(?:'.$this->auto_close_tags_re.')\b}', $tag) ||
+ $tag{1} == '!' || $tag{1} == '?')
+ {
+ # Just add the tag to the block as if it was text.
+ $block_text .= $tag;
+ }
+ else {
+ #
+ # Increase/decrease nested tag count. Only do so if
+ # the tag's name match base tag's.
+ #
+ if (preg_match('{^?'.$base_tag_name_re.'\b}', $tag)) {
+ if ($tag{1} == '/') $depth--;
+ else if ($tag{strlen($tag)-2} != '/') $depth++;
+ }
+
+ #
+ # Check for `markdown="1"` attribute and handle it.
+ #
+ if ($md_attr &&
+ preg_match($markdown_attr_re, $tag, $attr_m) &&
+ preg_match('/^1|block|span$/', $attr_m[2] . $attr_m[3]))
+ {
+ # Remove `markdown` attribute from opening tag.
+ $tag = preg_replace($markdown_attr_re, '', $tag);
+
+ # Check if text inside this tag must be parsed in span mode.
+ $this->mode = $attr_m[2] . $attr_m[3];
+ $span_mode = $this->mode == 'span' || $this->mode != 'block' &&
+ preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag);
+
+ # Calculate indent before tag.
+ if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
+ $strlen = $this->utf8_strlen;
+ $indent = $strlen($matches[1], 'UTF-8');
+ } else {
+ $indent = 0;
+ }
+
+ # End preceding block with this tag.
+ $block_text .= $tag;
+ $parsed .= $this->$hash_method($block_text);
+
+ # Get enclosing tag name for the ParseMarkdown function.
+ # (This pattern makes $tag_name_re safe without quoting.)
+ preg_match('/^<([\w:$]*)\b/', $tag, $matches);
+ $tag_name_re = $matches[1];
+
+ # Parse the content using the HTML-in-Markdown parser.
+ list ($block_text, $text)
+ = $this->_hashHTMLBlocks_inMarkdown($text, $indent,
+ $tag_name_re, $span_mode);
+
+ # Outdent markdown text.
+ if ($indent > 0) {
+ $block_text = preg_replace("/^[ ]{1,$indent}/m", "",
+ $block_text);
+ }
+
+ # Append tag content to parsed text.
+ if (!$span_mode) $parsed .= "\n\n$block_text\n\n";
+ else $parsed .= "$block_text";
+
+ # Start over a new block.
+ $block_text = "";
+ }
+ else $block_text .= $tag;
+ }
+
+ } while ($depth > 0);
+
+ #
+ # Hash last block text that wasn't processed inside the loop.
+ #
+ $parsed .= $this->$hash_method($block_text);
+
+ return array($parsed, $text);
+ }
+
+
+ function hashClean($text) {
+ #
+ # Called whenever a tag must be hashed when a function insert a "clean" tag
+ # in $text, it pass through this function and is automaticaly escaped,
+ # blocking invalid nested overlap.
+ #
+ return $this->hashPart($text, 'C');
+ }
+
+
+ function doHeaders($text) {
+ #
+ # Redefined to add id attribute support.
+ #
+ # Setext-style headers:
+ # Header 1 {#header1}
+ # ========
+ #
+ # Header 2 {#header2}
+ # --------
+ #
+ $text = preg_replace_callback(
+ '{
+ (^.+?) # $1: Header text
+ (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # $2: Id attribute
+ [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer
+ }mx',
+ array(&$this, '_doHeaders_callback_setext'), $text);
+
+ # atx-style headers:
+ # # Header 1 {#header1}
+ # ## Header 2 {#header2}
+ # ## Header 2 with closing hashes ## {#header3}
+ # ...
+ # ###### Header 6 {#header2}
+ #
+ $text = preg_replace_callback('{
+ ^(\#{1,6}) # $1 = string of #\'s
+ [ ]*
+ (.+?) # $2 = Header text
+ [ ]*
+ \#* # optional closing #\'s (not counted)
+ (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # id attribute
+ [ ]*
+ \n+
+ }xm',
+ array(&$this, '_doHeaders_callback_atx'), $text);
+
+ return $text;
+ }
+ function _doHeaders_attr($attr) {
+ if (empty($attr)) return "";
+ return " id=\"$attr\"";
+ }
+ function _doHeaders_callback_setext($matches) {
+ if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
+ return $matches[0];
+ $level = $matches[3]{0} == '=' ? 1 : 2;
+ $attr = $this->_doHeaders_attr($id =& $matches[2]);
+ $block = "".$this->runSpanGamut($matches[1])."";
+ return "\n" . $this->hashBlock($block) . "\n\n";
+ }
+ function _doHeaders_callback_atx($matches) {
+ $level = strlen($matches[1]);
+ $attr = $this->_doHeaders_attr($id =& $matches[3]);
+ $block = "".$this->runSpanGamut($matches[2])."";
+ return "\n" . $this->hashBlock($block) . "\n\n";
+ }
+
+
+ function doTables($text) {
+ #
+ # Form HTML tables.
+ #
+ $less_than_tab = $this->tab_width - 1;
+ #
+ # Find tables with leading pipe.
+ #
+ # | Header 1 | Header 2
+ # | -------- | --------
+ # | Cell 1 | Cell 2
+ # | Cell 3 | Cell 4
+ #
+ $text = preg_replace_callback('
+ {
+ ^ # Start of a line
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ [|] # Optional leading pipe (present)
+ (.+) \n # $1: Header row (at least one pipe)
+
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline
+
+ ( # $3: Cells
+ (?>
+ [ ]* # Allowed whitespace.
+ [|] .* \n # Row content.
+ )*
+ )
+ (?=\n|\Z) # Stop at final double newline.
+ }xm',
+ array(&$this, '_doTable_leadingPipe_callback'), $text);
+
+ #
+ # Find tables without leading pipe.
+ #
+ # Header 1 | Header 2
+ # -------- | --------
+ # Cell 1 | Cell 2
+ # Cell 3 | Cell 4
+ #
+ $text = preg_replace_callback('
+ {
+ ^ # Start of a line
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ (\S.*[|].*) \n # $1: Header row (at least one pipe)
+
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline
+
+ ( # $3: Cells
+ (?>
+ .* [|] .* \n # Row content
+ )*
+ )
+ (?=\n|\Z) # Stop at final double newline.
+ }xm',
+ array(&$this, '_DoTable_callback'), $text);
+
+ return $text;
+ }
+ function _doTable_leadingPipe_callback($matches) {
+ $head = $matches[1];
+ $underline = $matches[2];
+ $content = $matches[3];
+
+ # Remove leading pipe for each row.
+ $content = preg_replace('/^ *[|]/m', '', $content);
+
+ return $this->_doTable_callback(array($matches[0], $head, $underline, $content));
+ }
+ function _doTable_callback($matches) {
+ $head = $matches[1];
+ $underline = $matches[2];
+ $content = $matches[3];
+
+ # Remove any tailing pipes for each line.
+ $head = preg_replace('/[|] *$/m', '', $head);
+ $underline = preg_replace('/[|] *$/m', '', $underline);
+ $content = preg_replace('/[|] *$/m', '', $content);
+
+ # Reading alignement from header underline.
+ $separators = preg_split('/ *[|] */', $underline);
+ foreach ($separators as $n => $s) {
+ if (preg_match('/^ *-+: *$/', $s)) $attr[$n] = ' align="right"';
+ else if (preg_match('/^ *:-+: *$/', $s))$attr[$n] = ' align="center"';
+ else if (preg_match('/^ *:-+ *$/', $s)) $attr[$n] = ' align="left"';
+ else $attr[$n] = '';
+ }
+
+ # Parsing span elements, including code spans, character escapes,
+ # and inline HTML tags, so that pipes inside those gets ignored.
+ $head = $this->parseSpan($head);
+ $headers = preg_split('/ *[|] */', $head);
+ $col_count = count($headers);
+
+ # Write column headers.
+ $text = "
";
+
+ return $this->hashBlock($text) . "\n";
+ }
+
+
+ function doDefLists($text) {
+ #
+ # Form HTML definition lists.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Re-usable pattern to match any entire dl list:
+ $whole_list_re = '(?>
+ ( # $1 = whole list
+ ( # $2
+ [ ]{0,'.$less_than_tab.'}
+ ((?>.*\S.*\n)+) # $3 = defined term
+ \n?
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+ )
+ (?s:.+?)
+ ( # $4
+ \z
+ |
+ \n{2,}
+ (?=\S)
+ (?! # Negative lookahead for another term
+ [ ]{0,'.$less_than_tab.'}
+ (?: \S.*\n )+? # defined term
+ \n?
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+ )
+ (?! # Negative lookahead for another definition
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+ )
+ )
+ )
+ )'; // mx
+
+ $text = preg_replace_callback('{
+ (?>\A\n?|(?<=\n\n))
+ '.$whole_list_re.'
+ }mx',
+ array(&$this, '_doDefLists_callback'), $text);
+
+ return $text;
+ }
+ function _doDefLists_callback($matches) {
+ # Re-usable patterns to match list item bullets and number markers:
+ $list = $matches[1];
+
+ # Turn double returns into triple returns, so that we can make a
+ # paragraph for the last item in a list, if necessary:
+ $result = trim($this->processDefListItems($list));
+ $result = "
\n" . $result . "\n
";
+ return $this->hashBlock($result) . "\n\n";
+ }
+
+
+ function processDefListItems($list_str) {
+ #
+ # Process the contents of a single definition list, splitting it
+ # into individual term and definition list items.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # trim trailing blank lines:
+ $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+ # Process definition terms.
+ $list_str = preg_replace_callback('{
+ (?>\A\n?|\n\n+) # leading line
+ ( # definition terms = $1
+ [ ]{0,'.$less_than_tab.'} # leading whitespace
+ (?![:][ ]|[ ]) # negative lookahead for a definition
+ # mark (colon) or more whitespace.
+ (?> \S.* \n)+? # actual term (not whitespace).
+ )
+ (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed
+ # with a definition mark.
+ }xm',
+ array(&$this, '_processDefListItems_callback_dt'), $list_str);
+
+ # Process actual definitions.
+ $list_str = preg_replace_callback('{
+ \n(\n+)? # leading line = $1
+ ( # marker space = $2
+ [ ]{0,'.$less_than_tab.'} # whitespace before colon
+ [:][ ]+ # definition mark (colon)
+ )
+ ((?s:.+?)) # definition text = $3
+ (?= \n+ # stop at next definition mark,
+ (?: # next term or end of text
+ [ ]{0,'.$less_than_tab.'} [:][ ] |
+
";
+ return "\n\n".$this->hashBlock($codeblock)."\n\n";
+ }
+ function _doFencedCodeBlocks_newlines($matches) {
+ return str_repeat(" empty_element_suffix",
+ strlen($matches[0]));
+ }
+
+
+ #
+ # Redefining emphasis markers so that emphasis by underscore does not
+ # work in the middle of a word.
+ #
+ var $em_relist = array(
+ '' => '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? tags
+ #
+ # Strip leading and trailing lines:
+ $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+ $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+ #
+ # Wrap
tags and unhashify HTML blocks
+ #
+ foreach ($grafs as $key => $value) {
+ $value = trim($this->runSpanGamut($value));
+
+ # Check if this should be enclosed in a paragraph.
+ # Clean tag hashes & block tag hashes are left alone.
+ $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value);
+
+ if ($is_p) {
+ $value = "
$value
";
+ }
+ $grafs[$key] = $value;
+ }
+
+ # Join grafs in one text, then unhash HTML tags.
+ $text = implode("\n\n", $grafs);
+
+ # Finish by removing any tag hashes still present in $text.
+ $text = $this->unhash($text);
+
+ return $text;
+ }
+
+
+ ### Footnotes
+
+ function stripFootnotes($text) {
+ #
+ # Strips link definitions from text, stores the URLs and titles in
+ # hash references.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Link defs are in the form: [^id]: url "optional title"
+ $text = preg_replace_callback('{
+ ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?: # note_id = $1
+ [ ]*
+ \n? # maybe *one* newline
+ ( # text = $2 (no blank lines allowed)
+ (?:
+ .+ # actual text
+ |
+ \n # newlines but
+ (?!\[\^.+?\]:\s)# negative lookahead for footnote marker.
+ (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed
+ # by non-indented content
+ )*
+ )
+ }xm',
+ array(&$this, '_stripFootnotes_callback'),
+ $text);
+ return $text;
+ }
+ function _stripFootnotes_callback($matches) {
+ $note_id = $this->fn_id_prefix . $matches[1];
+ $this->footnotes[$note_id] = $this->outdent($matches[2]);
+ return ''; # String that will replace the block
+ }
+
+
+ function doFootnotes($text) {
+ #
+ # Replace footnote references in $text [^id] with a special text-token
+ # which will be replaced by the actual footnote marker in appendFootnotes.
+ #
+ if (!$this->in_anchor) {
+ $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text);
+ }
+ return $text;
+ }
+
+
+ function appendFootnotes($text) {
+ #
+ # Append footnote list to text.
+ #
+ $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
+ array(&$this, '_appendFootnotes_callback'), $text);
+
+ if (!empty($this->footnotes_ordered)) {
+ $text .= "\n\n";
+ $text .= "
";
+ }
+ return $text;
+ }
+ function _appendFootnotes_callback($matches) {
+ $node_id = $this->fn_id_prefix . $matches[1];
+
+ # Create footnote marker only if it has a corresponding footnote *and*
+ # the footnote hasn't been used by another marker.
+ if (isset($this->footnotes[$node_id])) {
+ # Transfert footnote content to the ordered list.
+ $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id];
+ unset($this->footnotes[$node_id]);
+
+ $num = $this->footnote_counter++;
+ $attr = " rel=\"footnote\"";
+ if ($this->fn_link_class != "") {
+ $class = $this->fn_link_class;
+ $class = $this->encodeAttribute($class);
+ $attr .= " class=\"$class\"";
+ }
+ if ($this->fn_link_title != "") {
+ $title = $this->fn_link_title;
+ $title = $this->encodeAttribute($title);
+ $attr .= " title=\"$title\"";
+ }
+
+ $attr = str_replace("%%", $num, $attr);
+ $node_id = $this->encodeAttribute($node_id);
+
+ return
+ "".
+ "$num".
+ "";
+ }
+
+ return "[^".$matches[1]."]";
+ }
+
+
+ ### Abbreviations ###
+
+ function stripAbbreviations($text) {
+ #
+ # Strips abbreviations from text, stores titles in hash references.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Link defs are in the form: [id]*: url "optional title"
+ $text = preg_replace_callback('{
+ ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1
+ (.*) # text = $2 (no blank lines allowed)
+ }xm',
+ array(&$this, '_stripAbbreviations_callback'),
+ $text);
+ return $text;
+ }
+ function _stripAbbreviations_callback($matches) {
+ $abbr_word = $matches[1];
+ $abbr_desc = $matches[2];
+ if ($this->abbr_word_re)
+ $this->abbr_word_re .= '|';
+ $this->abbr_word_re .= preg_quote($abbr_word);
+ $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+ return ''; # String that will replace the block
+ }
+
+
+ function doAbbreviations($text) {
+ #
+ # Find defined abbreviations in text and wrap them in elements.
+ #
+ if ($this->abbr_word_re) {
+ // cannot use the /x modifier because abbr_word_re may
+ // contain significant spaces:
+ $text = preg_replace_callback('{'.
+ '(?abbr_word_re.')'.
+ '(?![\w\x1A])'.
+ '}',
+ array(&$this, '_doAbbreviations_callback'), $text);
+ }
+ return $text;
+ }
+ function _doAbbreviations_callback($matches) {
+ $abbr = $matches[0];
+ if (isset($this->abbr_desciptions[$abbr])) {
+ $desc = $this->abbr_desciptions[$abbr];
+ if (empty($desc)) {
+ return $this->hashPart("$abbr");
+ } else {
+ $desc = $this->encodeAttribute($desc);
+ return $this->hashPart("$abbr");
+ }
+ } else {
+ return $matches[0];
+ }
+ }
+
+}
+
+
+/*
+
+PHP Markdown Extra
+==================
+
+Description
+-----------
+
+This is a PHP port of the original Markdown formatter written in Perl
+by John Gruber. This special "Extra" version of PHP Markdown features
+further enhancements to the syntax for making additional constructs
+such as tables and definition list.
+
+Markdown is a text-to-HTML filter; it translates an easy-to-read /
+easy-to-write structured text format into HTML. Markdown's text format
+is most similar to that of plain text email, and supports features such
+as headers, *emphasis*, code blocks, blockquotes, and links.
+
+Markdown's syntax is designed not as a generic markup language, but
+specifically to serve as a front-end to (X)HTML. You can use span-level
+HTML tags anywhere in a Markdown document, and you can use block level
+HTML tags (like
and
as well).
+
+For more information about Markdown's syntax, see:
+
+
+
+
+Bugs
+----
+
+To file bug reports please send email to:
+
+
+
+Please include with your report: (1) the example input; (2) the output you
+expected; (3) the output Markdown actually produced.
+
+
+Version History
+---------------
+
+See the readme file for detailed release notes for this version.
+
+
+Copyright and License
+---------------------
+
+PHP Markdown & Extra
+Copyright (c) 2004-2008 Michel Fortin
+
+All rights reserved.
+
+Based on Markdown
+Copyright (c) 2003-2006 John Gruber
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name "Markdown" nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+This software is provided by the copyright holders and contributors "as
+is" and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed. In no event shall the copyright owner
+or contributors be liable for any direct, indirect, incidental, special,
+exemplary, or consequential damages (including, but not limited to,
+procurement of substitute goods or services; loss of use, data, or
+profits; or business interruption) however caused and on any theory of
+liability, whether in contract, strict liability, or tort (including
+negligence or otherwise) arising in any way out of the use of this
+software, even if advised of the possibility of such damage.
+
+*/
+?>
\ No newline at end of file
diff --git a/system/application/libraries/.svn/text-base/page.php.svn-base b/system/application/libraries/.svn/text-base/page.php.svn-base
new file mode 100644
index 0000000..e94d149
--- /dev/null
+++ b/system/application/libraries/.svn/text-base/page.php.svn-base
@@ -0,0 +1,210 @@
+currentPage = (integer) abs($reqCurrentPage);
+ }
+
+ function SetItemCount($reqItemCount){
+ $this->itemCount = (integer) abs($reqItemCount);
+ }
+
+ function SetItemsPerPage($reqItemsPerPage){
+ $this->itemsPerPage = (integer) abs($reqItemsPerPage);
+ }
+
+ function SetLinksHref($reqLinksHref){
+ $this->linksHref = $reqLinksHref;
+ }
+
+ function SetLinksFormat($reqPageJumpBack, $reqPageSeparator, $reqPageJumpNext){
+ $this->pageJumpBack = $reqPageJumpBack;
+ $this->pageSeparator = $reqPageSeparator;
+ $this->pageJumpNext = $reqPageJumpNext;
+ }
+
+ function SetLinksToDisplay($reqLinksToDisplay){
+ $this->linksToDisplay = (integer) abs($reqLinksToDisplay);
+ }
+
+ function SetQueryStringVar($reqQueryStringVar){
+ $this->queryStringVar = $reqQueryStringVar;
+ }
+
+ function SetQueryString($reqQueryString){
+ $this->queryString = $reqQueryString;
+ }
+
+ function GetCurrentCollection($reqCollection){
+ if($this->currentPage < 1){
+ $start = 0;
+ }
+ elseif($this->currentPage > $this->GetPageCount()){
+ $start = $this->GetPageCount() * $this->itemsPerPage - $this->itemsPerPage;
+ }
+ else {
+ $start = $this->currentPage * $this->itemsPerPage - $this->itemsPerPage;
+ }
+
+ return array_slice($reqCollection, $start, $this->itemsPerPage);
+ }
+
+ function GetPageCount(){
+ return (integer)ceil($this->itemCount/$this->itemsPerPage);
+ }
+
+ function GetPageLinks(){
+ $strLinks = '';
+ $pageCount = $this->GetPageCount();
+ $queryString = $this->GetQueryString();
+ $linksPad = floor($this->linksToDisplay/2);
+
+ if($this->linksToDisplay == -1){
+ $this->linksToDisplay = $pageCount;
+ }
+
+
+ if($pageCount == 0){
+ $strLinks = '1';
+ }
+ elseif($this->currentPage - 1 <= $linksPad || ($pageCount - $this->linksToDisplay + 1 == 0) || $this->linksToDisplay > $pageCount){
+ $start = 1;
+ }
+ elseif($pageCount - $this->currentPage <= $linksPad){
+ $start = $pageCount - $this->linksToDisplay + 1;
+ }
+ else {
+ $start = $this->currentPage - $linksPad;
+ }
+
+
+ if(isset($start)){
+ if($start > 1){
+ if(!empty($this->pageJumpBack)){
+ $pageNum = $start - $this->linksToDisplay + $linksPad;
+ if($pageNum < 1){
+ $pageNum = 1;
+ }
+
+ $strLinks .= '';
+ $strLinks .= $this->pageJumpBack.''.$this->pageSeparator;
+ }
+
+ $strLinks .= '1...'.$this->pageSeparator;
+ }
+
+
+ if($start + $this->linksToDisplay > $pageCount){
+ $end = $pageCount;
+ }
+ else {
+ $end = $start + $this->linksToDisplay - 1;
+ }
+
+
+ for($i = $start; $i <= $end; $i ++){
+ if($i != $this->currentPage){
+ $strLinks .= '';
+ $strLinks .= ($i).''.$this->pageSeparator;
+ }
+ else {
+ $strLinks .= $i.$this->pageSeparator;
+ }
+ }
+ $strLinks = substr($strLinks, 0, -strlen($this->pageSeparator));
+
+
+ if($start + $this->linksToDisplay - 1 < $pageCount){
+ $strLinks .= $this->pageSeparator.'';
+ $strLinks .= '...'.$pageCount.''.$this->pageSeparator;
+
+ if(!empty($this->pageJumpNext)){
+ $pageNum = $start + $this->linksToDisplay + $linksPad;
+ if($pageNum > $pageCount){
+ $pageNum = $pageCount;
+ }
+
+ $strLinks .= '';
+ $strLinks .= $this->pageJumpNext.'';
+ }
+ }
+ }
+
+
+ return $strLinks;
+ }
+
+ function GetQueryString(){
+ $pattern = array('/'.$this->queryStringVar.'=[^&]*&?/', '/&$/');
+ $replace = array('', '');
+ $queryString = preg_replace($pattern, $replace, $this->queryString);
+ $queryString = str_replace('&', '&', $queryString);
+
+ if(!empty($queryString)){
+ $queryString.= '&';
+ }
+
+ return "page/";
+ }
+
+ function GetSqlLimit(){
+ return $this->itemsPerPage;
+ }
+
+ function GetOffset(){
+ return $this->currentPage * $this->itemsPerPage - $this->itemsPerPage;
+ }
+
+ function GetLimit(){
+ return $this->itemsPerPage;
+ }
+
+ function __Construct(){
+ $this->SetCurrentPage(1);
+ $this->SetItemsPerPage(10);
+ $this->SetItemCount(0);
+ $this->SetLinksFormat('« Back',' • ','Next »');
+ $this->SetLinksHref($_SERVER['PHP_SELF']);
+ $this->SetLinksToDisplay(10);
+ $this->SetQueryStringVar('page');
+ $this->SetQueryString($_SERVER['QUERY_STRING']);
+
+ if(isset($_GET[$this->queryStringVar]) && is_numeric($_GET[$this->queryStringVar])){
+ $this->SetCurrentPage($_GET[$this->queryStringVar]);
+ }
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/system/application/libraries/.svn/text-base/simplepie.php.svn-base b/system/application/libraries/.svn/text-base/simplepie.php.svn-base
new file mode 100644
index 0000000..f5cd9a7
--- /dev/null
+++ b/system/application/libraries/.svn/text-base/simplepie.php.svn-base
@@ -0,0 +1,13284 @@
+' . SIMPLEPIE_NAME . '');
+
+/**
+ * No Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_NONE', 0);
+
+/**
+ * Feed Link Element Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
+
+/**
+ * Local Feed Extension Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
+
+/**
+ * Local Feed Body Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
+
+/**
+ * Remote Feed Extension Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
+
+/**
+ * Remote Feed Body Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
+
+/**
+ * All Feed Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_ALL', 31);
+
+/**
+ * No known feed type
+ */
+define('SIMPLEPIE_TYPE_NONE', 0);
+
+/**
+ * RSS 0.90
+ */
+define('SIMPLEPIE_TYPE_RSS_090', 1);
+
+/**
+ * RSS 0.91 (Netscape)
+ */
+define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
+
+/**
+ * RSS 0.91 (Userland)
+ */
+define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
+
+/**
+ * RSS 0.91 (both Netscape and Userland)
+ */
+define('SIMPLEPIE_TYPE_RSS_091', 6);
+
+/**
+ * RSS 0.92
+ */
+define('SIMPLEPIE_TYPE_RSS_092', 8);
+
+/**
+ * RSS 0.93
+ */
+define('SIMPLEPIE_TYPE_RSS_093', 16);
+
+/**
+ * RSS 0.94
+ */
+define('SIMPLEPIE_TYPE_RSS_094', 32);
+
+/**
+ * RSS 1.0
+ */
+define('SIMPLEPIE_TYPE_RSS_10', 64);
+
+/**
+ * RSS 2.0
+ */
+define('SIMPLEPIE_TYPE_RSS_20', 128);
+
+/**
+ * RDF-based RSS
+ */
+define('SIMPLEPIE_TYPE_RSS_RDF', 65);
+
+/**
+ * Non-RDF-based RSS (truly intended as syndication format)
+ */
+define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
+
+/**
+ * All RSS
+ */
+define('SIMPLEPIE_TYPE_RSS_ALL', 255);
+
+/**
+ * Atom 0.3
+ */
+define('SIMPLEPIE_TYPE_ATOM_03', 256);
+
+/**
+ * Atom 1.0
+ */
+define('SIMPLEPIE_TYPE_ATOM_10', 512);
+
+/**
+ * All Atom
+ */
+define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
+
+/**
+ * All feed types
+ */
+define('SIMPLEPIE_TYPE_ALL', 1023);
+
+/**
+ * No construct
+ */
+define('SIMPLEPIE_CONSTRUCT_NONE', 0);
+
+/**
+ * Text construct
+ */
+define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
+
+/**
+ * HTML construct
+ */
+define('SIMPLEPIE_CONSTRUCT_HTML', 2);
+
+/**
+ * XHTML construct
+ */
+define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
+
+/**
+ * base64-encoded construct
+ */
+define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
+
+/**
+ * IRI construct
+ */
+define('SIMPLEPIE_CONSTRUCT_IRI', 16);
+
+/**
+ * A construct that might be HTML
+ */
+define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
+
+/**
+ * All constructs
+ */
+define('SIMPLEPIE_CONSTRUCT_ALL', 63);
+
+/**
+ * PCRE for HTML attributes
+ */
+define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
+
+/**
+ * PCRE for XML attributes
+ */
+define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
+
+/**
+ * XML Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
+
+/**
+ * Atom 1.0 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
+
+/**
+ * Atom 0.3 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
+
+/**
+ * RDF Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
+
+/**
+ * RSS 0.90 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
+
+/**
+ * RSS 1.0 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
+
+/**
+ * RSS 1.0 Content Module Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
+
+/**
+ * DC 1.0 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
+
+/**
+ * DC 1.1 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
+
+/**
+ * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
+
+/**
+ * GeoRSS Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
+
+/**
+ * Media RSS Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
+
+/**
+ * iTunes RSS Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
+
+/**
+ * XHTML Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
+
+/**
+ * IANA Link Relations Registry
+ */
+define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
+
+/**
+ * Whether we're running on PHP5
+ */
+define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
+
+/**
+ * No file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
+
+/**
+ * Remote file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
+
+/**
+ * Local file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
+
+/**
+ * fsockopen() file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
+
+/**
+ * cURL file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
+
+/**
+ * file_get_contents() file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
+
+/**
+ * SimplePie
+ *
+ * @package SimplePie
+ * @version "Razzleberry"
+ * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
+ * @author Ryan Parman
+ * @author Geoffrey Sneddon
+ * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
+ */
+class SimplePie
+{
+ /**
+ * @var array Raw data
+ * @access private
+ */
+ var $data = array();
+
+ /**
+ * @var mixed Error string
+ * @access private
+ */
+ var $error;
+
+ /**
+ * @var object Instance of SimplePie_Sanitize (or other class)
+ * @see SimplePie::set_sanitize_class()
+ * @access private
+ */
+ var $sanitize;
+
+ /**
+ * @var string SimplePie Useragent
+ * @see SimplePie::set_useragent()
+ * @access private
+ */
+ var $useragent = SIMPLEPIE_USERAGENT;
+
+ /**
+ * @var string Feed URL
+ * @see SimplePie::set_feed_url()
+ * @access private
+ */
+ var $feed_url;
+
+ /**
+ * @var object Instance of SimplePie_File to use as a feed
+ * @see SimplePie::set_file()
+ * @access private
+ */
+ var $file;
+
+ /**
+ * @var string Raw feed data
+ * @see SimplePie::set_raw_data()
+ * @access private
+ */
+ var $raw_data;
+
+ /**
+ * @var int Timeout for fetching remote files
+ * @see SimplePie::set_timeout()
+ * @access private
+ */
+ var $timeout = 10;
+
+ /**
+ * @var bool Forces fsockopen() to be used for remote files instead
+ * of cURL, even if a new enough version is installed
+ * @see SimplePie::force_fsockopen()
+ * @access private
+ */
+ var $force_fsockopen = false;
+
+ /**
+ * @var bool Force the given data/URL to be treated as a feed no matter what
+ * it appears like
+ * @see SimplePie::force_feed()
+ * @access private
+ */
+ var $force_feed = false;
+
+ /**
+ * @var bool Enable/Disable XML dump
+ * @see SimplePie::enable_xml_dump()
+ * @access private
+ */
+ var $xml_dump = false;
+
+ /**
+ * @var bool Enable/Disable Caching
+ * @see SimplePie::enable_cache()
+ * @access private
+ */
+ var $cache = true;
+
+ /**
+ * @var int Cache duration (in seconds)
+ * @see SimplePie::set_cache_duration()
+ * @access private
+ */
+ var $cache_duration = 3600;
+
+ /**
+ * @var int Auto-discovery cache duration (in seconds)
+ * @see SimplePie::set_autodiscovery_cache_duration()
+ * @access private
+ */
+ var $autodiscovery_cache_duration = 604800; // 7 Days.
+
+ /**
+ * @var string Cache location (relative to executing script)
+ * @see SimplePie::set_cache_location()
+ * @access private
+ */
+ var $cache_location = './cache';
+
+ /**
+ * @var string Function that creates the cache filename
+ * @see SimplePie::set_cache_name_function()
+ * @access private
+ */
+ var $cache_name_function = 'md5';
+
+ /**
+ * @var bool Reorder feed by date descending
+ * @see SimplePie::enable_order_by_date()
+ * @access private
+ */
+ var $order_by_date = true;
+
+ /**
+ * @var mixed Force input encoding to be set to the follow value
+ * (false, or anything type-cast to false, disables this feature)
+ * @see SimplePie::set_input_encoding()
+ * @access private
+ */
+ var $input_encoding = false;
+
+ /**
+ * @var int Feed Autodiscovery Level
+ * @see SimplePie::set_autodiscovery_level()
+ * @access private
+ */
+ var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
+
+ /**
+ * @var string Class used for caching feeds
+ * @see SimplePie::set_cache_class()
+ * @access private
+ */
+ var $cache_class = 'SimplePie_Cache';
+
+ /**
+ * @var string Class used for locating feeds
+ * @see SimplePie::set_locator_class()
+ * @access private
+ */
+ var $locator_class = 'SimplePie_Locator';
+
+ /**
+ * @var string Class used for parsing feeds
+ * @see SimplePie::set_parser_class()
+ * @access private
+ */
+ var $parser_class = 'SimplePie_Parser';
+
+ /**
+ * @var string Class used for fetching feeds
+ * @see SimplePie::set_file_class()
+ * @access private
+ */
+ var $file_class = 'SimplePie_File';
+
+ /**
+ * @var string Class used for items
+ * @see SimplePie::set_item_class()
+ * @access private
+ */
+ var $item_class = 'SimplePie_Item';
+
+ /**
+ * @var string Class used for authors
+ * @see SimplePie::set_author_class()
+ * @access private
+ */
+ var $author_class = 'SimplePie_Author';
+
+ /**
+ * @var string Class used for categories
+ * @see SimplePie::set_category_class()
+ * @access private
+ */
+ var $category_class = 'SimplePie_Category';
+
+ /**
+ * @var string Class used for enclosures
+ * @see SimplePie::set_enclosures_class()
+ * @access private
+ */
+ var $enclosure_class = 'SimplePie_Enclosure';
+
+ /**
+ * @var string Class used for Media RSS captions
+ * @see SimplePie::set_caption_class()
+ * @access private
+ */
+ var $caption_class = 'SimplePie_Caption';
+
+ /**
+ * @var string Class used for Media RSS
+ * @see SimplePie::set_copyright_class()
+ * @access private
+ */
+ var $copyright_class = 'SimplePie_Copyright';
+
+ /**
+ * @var string Class used for Media RSS
+ * @see SimplePie::set_credit_class()
+ * @access private
+ */
+ var $credit_class = 'SimplePie_Credit';
+
+ /**
+ * @var string Class used for Media RSS
+ * @see SimplePie::set_rating_class()
+ * @access private
+ */
+ var $rating_class = 'SimplePie_Rating';
+
+ /**
+ * @var string Class used for Media RSS
+ * @see SimplePie::set_restriction_class()
+ * @access private
+ */
+ var $restriction_class = 'SimplePie_Restriction';
+
+ /**
+ * @var string Class used for content-type sniffing
+ * @see SimplePie::set_content_type_sniffer_class()
+ * @access private
+ */
+ var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
+
+ /**
+ * @var string Class used for item sources.
+ * @see SimplePie::set_source_class()
+ * @access private
+ */
+ var $source_class = 'SimplePie_Source';
+
+ /**
+ * @var mixed Set javascript query string parameter (false, or
+ * anything type-cast to false, disables this feature)
+ * @see SimplePie::set_javascript()
+ * @access private
+ */
+ var $javascript = 'js';
+
+ /**
+ * @var int Maximum number of feeds to check with autodiscovery
+ * @see SimplePie::set_max_checked_feeds()
+ * @access private
+ */
+ var $max_checked_feeds = 10;
+
+ /**
+ * @var string Web-accessible path to the handler_favicon.php file.
+ * @see SimplePie::set_favicon_handler()
+ * @access private
+ */
+ var $favicon_handler = '';
+
+ /**
+ * @var string Web-accessible path to the handler_image.php file.
+ * @see SimplePie::set_image_handler()
+ * @access private
+ */
+ var $image_handler = '';
+
+ /**
+ * @var array Stores the URLs when multiple feeds are being initialized.
+ * @see SimplePie::set_feed_url()
+ * @access private
+ */
+ var $multifeed_url = array();
+
+ /**
+ * @var array Stores SimplePie objects when multiple feeds initialized.
+ * @access private
+ */
+ var $multifeed_objects = array();
+
+ /**
+ * @var array Stores the get_object_vars() array for use with multifeeds.
+ * @see SimplePie::set_feed_url()
+ * @access private
+ */
+ var $config_settings = null;
+
+ /**
+ * @var integer Stores the number of items to return per-feed with multifeeds.
+ * @see SimplePie::set_item_limit()
+ * @access private
+ */
+ var $item_limit = 0;
+
+ /**
+ * @var array Stores the default attributes to be stripped by strip_attributes().
+ * @see SimplePie::strip_attributes()
+ * @access private
+ */
+ var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
+
+ /**
+ * @var array Stores the default tags to be stripped by strip_htmltags().
+ * @see SimplePie::strip_htmltags()
+ * @access private
+ */
+ var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
+
+ /**
+ * The SimplePie class contains feed level data and options
+ *
+ * There are two ways that you can create a new SimplePie object. The first
+ * is by passing a feed URL as a parameter to the SimplePie constructor
+ * (as well as optionally setting the cache location and cache expiry). This
+ * will initialise the whole feed with all of the default settings, and you
+ * can begin accessing methods and properties immediately.
+ *
+ * The second way is to create the SimplePie object with no parameters
+ * at all. This will enable you to set configuration options. After setting
+ * them, you must initialise the feed using $feed->init(). At that point the
+ * object's methods and properties will be available to you. This format is
+ * what is used throughout this documentation.
+ *
+ * @access public
+ * @since 1.0 Preview Release
+ * @param string $feed_url This is the URL you want to parse.
+ * @param string $cache_location This is where you want the cache to be stored.
+ * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
+ */
+ function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
+ {
+ // Other objects, instances created here so we can set options on them
+ $this->sanitize =& new SimplePie_Sanitize;
+
+ // Set options if they're passed to the constructor
+ if ($cache_location !== null)
+ {
+ $this->set_cache_location($cache_location);
+ }
+
+ if ($cache_duration !== null)
+ {
+ $this->set_cache_duration($cache_duration);
+ }
+
+ // Only init the script if we're passed a feed URL
+ if ($feed_url !== null)
+ {
+ $this->set_feed_url($feed_url);
+ $this->init();
+ }
+ }
+
+ /**
+ * Used for converting object to a string
+ */
+ function __toString()
+ {
+ return md5(serialize($this->data));
+ }
+
+ /**
+ * Remove items that link back to this before destroying this object
+ */
+ function __destruct()
+ {
+ if (!empty($this->data['items']))
+ {
+ foreach ($this->data['items'] as $item)
+ {
+ $item->__destruct();
+ }
+ unset($this->data['items']);
+ }
+ if (!empty($this->data['ordered_items']))
+ {
+ foreach ($this->data['ordered_items'] as $item)
+ {
+ $item->__destruct();
+ }
+ unset($this->data['ordered_items']);
+ }
+ }
+
+ /**
+ * Force the given data/URL to be treated as a feed no matter what it
+ * appears like
+ *
+ * @access public
+ * @since 1.1
+ * @param bool $enable Force the given data/URL to be treated as a feed
+ */
+ function force_feed($enable = false)
+ {
+ $this->force_feed = (bool) $enable;
+ }
+
+ /**
+ * This is the URL of the feed you want to parse.
+ *
+ * This allows you to enter the URL of the feed you want to parse, or the
+ * website you want to try to use auto-discovery on. This takes priority
+ * over any set raw data.
+ *
+ * You can set multiple feeds to mash together by passing an array instead
+ * of a string for the $url. Remember that with each additional feed comes
+ * additional processing and resources.
+ *
+ * @access public
+ * @since 1.0 Preview Release
+ * @param mixed $url This is the URL (or array of URLs) that you want to parse.
+ * @see SimplePie::set_raw_data()
+ */
+ function set_feed_url($url)
+ {
+ if (is_array($url))
+ {
+ $this->multifeed_url = array();
+ foreach ($url as $value)
+ {
+ $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
+ }
+ }
+ else
+ {
+ $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
+ }
+ }
+
+ /**
+ * Provides an instance of SimplePie_File to use as a feed
+ *
+ * @access public
+ * @param object &$file Instance of SimplePie_File (or subclass)
+ * @return bool True on success, false on failure
+ */
+ function set_file(&$file)
+ {
+ if (is_a($file, 'SimplePie_File'))
+ {
+ $this->feed_url = $file->url;
+ $this->file =& $file;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to use a string of RSS/Atom data instead of a remote feed.
+ *
+ * If you have a feed available as a string in PHP, you can tell SimplePie
+ * to parse that data string instead of a remote feed. Any set feed URL
+ * takes precedence.
+ *
+ * @access public
+ * @since 1.0 Beta 3
+ * @param string $data RSS or Atom data as a string.
+ * @see SimplePie::set_feed_url()
+ */
+ function set_raw_data($data)
+ {
+ $this->raw_data = trim($data);
+ }
+
+ /**
+ * Allows you to override the default timeout for fetching remote feeds.
+ *
+ * This allows you to change the maximum time the feed's server to respond
+ * and send the feed back.
+ *
+ * @access public
+ * @since 1.0 Beta 3
+ * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
+ */
+ function set_timeout($timeout = 10)
+ {
+ $this->timeout = (int) $timeout;
+ }
+
+ /**
+ * Forces SimplePie to use fsockopen() instead of the preferred cURL
+ * functions.
+ *
+ * @access public
+ * @since 1.0 Beta 3
+ * @param bool $enable Force fsockopen() to be used
+ */
+ function force_fsockopen($enable = false)
+ {
+ $this->force_fsockopen = (bool) $enable;
+ }
+
+ /**
+ * Outputs the raw XML content of the feed, after it has gone through
+ * SimplePie's filters.
+ *
+ * Used only for debugging, this function will output the XML content as
+ * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
+ * before trying to parse it. Many parts of the feed are re-written in
+ * memory, and in the end, you have a parsable feed. XML dump shows you the
+ * actual XML that SimplePie tries to parse, which may or may not be very
+ * different from the original feed.
+ *
+ * @access public
+ * @since 1.0 Preview Release
+ * @param bool $enable Enable XML dump
+ */
+ function enable_xml_dump($enable = false)
+ {
+ $this->xml_dump = (bool) $enable;
+ }
+
+ /**
+ * Enables/disables caching in SimplePie.
+ *
+ * This option allows you to disable caching all-together in SimplePie.
+ * However, disabling the cache can lead to longer load times.
+ *
+ * @access public
+ * @since 1.0 Preview Release
+ * @param bool $enable Enable caching
+ */
+ function enable_cache($enable = true)
+ {
+ $this->cache = (bool) $enable;
+ }
+
+ /**
+ * Set the length of time (in seconds) that the contents of a feed
+ * will be cached.
+ *
+ * @access public
+ * @param int $seconds The feed content cache duration.
+ */
+ function set_cache_duration($seconds = 3600)
+ {
+ $this->cache_duration = (int) $seconds;
+ }
+
+ /**
+ * Set the length of time (in seconds) that the autodiscovered feed
+ * URL will be cached.
+ *
+ * @access public
+ * @param int $seconds The autodiscovered feed URL cache duration.
+ */
+ function set_autodiscovery_cache_duration($seconds = 604800)
+ {
+ $this->autodiscovery_cache_duration = (int) $seconds;
+ }
+
+ /**
+ * Set the file system location where the cached files should be stored.
+ *
+ * @access public
+ * @param string $location The file system location.
+ */
+ function set_cache_location($location = './cache')
+ {
+ $this->cache_location = (string) $location;
+ }
+
+ /**
+ * Determines whether feed items should be sorted into reverse chronological order.
+ *
+ * @access public
+ * @param bool $enable Sort as reverse chronological order.
+ */
+ function enable_order_by_date($enable = true)
+ {
+ $this->order_by_date = (bool) $enable;
+ }
+
+ /**
+ * Allows you to override the character encoding reported by the feed.
+ *
+ * @access public
+ * @param string $encoding Character encoding.
+ */
+ function set_input_encoding($encoding = false)
+ {
+ if ($encoding)
+ {
+ $this->input_encoding = (string) $encoding;
+ }
+ else
+ {
+ $this->input_encoding = false;
+ }
+ }
+
+ /**
+ * Set how much feed autodiscovery to do
+ *
+ * @access public
+ * @see SIMPLEPIE_LOCATOR_NONE
+ * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
+ * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
+ * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
+ * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
+ * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
+ * @see SIMPLEPIE_LOCATOR_ALL
+ * @param int $level Feed Autodiscovery Level (level can be a
+ * combination of the above constants, see bitwise OR operator)
+ */
+ function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
+ {
+ $this->autodiscovery = (int) $level;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for caching.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_cache_class($class = 'SimplePie_Cache')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
+ {
+ $this->cache_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for auto-discovery.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_locator_class($class = 'SimplePie_Locator')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
+ {
+ $this->locator_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for XML parsing.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_parser_class($class = 'SimplePie_Parser')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
+ {
+ $this->parser_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for remote file fetching.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_file_class($class = 'SimplePie_File')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
+ {
+ $this->file_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for data sanitization.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_sanitize_class($class = 'SimplePie_Sanitize')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
+ {
+ $this->sanitize =& new $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for handling feed items.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_item_class($class = 'SimplePie_Item')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
+ {
+ $this->item_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for handling author data.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_author_class($class = 'SimplePie_Author')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
+ {
+ $this->author_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for handling category data.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_category_class($class = 'SimplePie_Category')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
+ {
+ $this->category_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for feed enclosures.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_enclosure_class($class = 'SimplePie_Enclosure')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
+ {
+ $this->enclosure_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for captions
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_caption_class($class = 'SimplePie_Caption')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
+ {
+ $this->caption_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_copyright_class($class = 'SimplePie_Copyright')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
+ {
+ $this->copyright_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_credit_class($class = 'SimplePie_Credit')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
+ {
+ $this->credit_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_rating_class($class = 'SimplePie_Rating')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
+ {
+ $this->rating_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_restriction_class($class = 'SimplePie_Restriction')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
+ {
+ $this->restriction_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for content-type sniffing.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
+ {
+ $this->content_type_sniffer_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses item sources.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_source_class($class = 'SimplePie_Source')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
+ {
+ $this->source_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to override the default user agent string.
+ *
+ * @access public
+ * @param string $ua New user agent string.
+ */
+ function set_useragent($ua = SIMPLEPIE_USERAGENT)
+ {
+ $this->useragent = (string) $ua;
+ }
+
+ /**
+ * Set callback function to create cache filename with
+ *
+ * @access public
+ * @param mixed $function Callback function
+ */
+ function set_cache_name_function($function = 'md5')
+ {
+ if (is_callable($function))
+ {
+ $this->cache_name_function = $function;
+ }
+ }
+
+ /**
+ * Set javascript query string parameter
+ *
+ * @access public
+ * @param mixed $get Javascript query string parameter
+ */
+ function set_javascript($get = 'js')
+ {
+ if ($get)
+ {
+ $this->javascript = (string) $get;
+ }
+ else
+ {
+ $this->javascript = false;
+ }
+ }
+
+ /**
+ * Set options to make SP as fast as possible. Forgoes a
+ * substantial amount of data sanitization in favor of speed.
+ *
+ * @access public
+ * @param bool $set Whether to set them or not
+ */
+ function set_stupidly_fast($set = false)
+ {
+ if ($set)
+ {
+ $this->enable_order_by_date(false);
+ $this->remove_div(false);
+ $this->strip_comments(false);
+ $this->strip_htmltags(false);
+ $this->strip_attributes(false);
+ $this->set_image_handler(false);
+ }
+ }
+
+ /**
+ * Set maximum number of feeds to check with autodiscovery
+ *
+ * @access public
+ * @param int $max Maximum number of feeds to check
+ */
+ function set_max_checked_feeds($max = 10)
+ {
+ $this->max_checked_feeds = (int) $max;
+ }
+
+ function remove_div($enable = true)
+ {
+ $this->sanitize->remove_div($enable);
+ }
+
+ function strip_htmltags($tags = '', $encode = null)
+ {
+ if ($tags === '')
+ {
+ $tags = $this->strip_htmltags;
+ }
+ $this->sanitize->strip_htmltags($tags);
+ if ($encode !== null)
+ {
+ $this->sanitize->encode_instead_of_strip($tags);
+ }
+ }
+
+ function encode_instead_of_strip($enable = true)
+ {
+ $this->sanitize->encode_instead_of_strip($enable);
+ }
+
+ function strip_attributes($attribs = '')
+ {
+ if ($attribs === '')
+ {
+ $attribs = $this->strip_attributes;
+ }
+ $this->sanitize->strip_attributes($attribs);
+ }
+
+ function set_output_encoding($encoding = 'UTF-8')
+ {
+ $this->sanitize->set_output_encoding($encoding);
+ }
+
+ function strip_comments($strip = false)
+ {
+ $this->sanitize->strip_comments($strip);
+ }
+
+ /**
+ * Set element/attribute key/value pairs of HTML attributes
+ * containing URLs that need to be resolved relative to the feed
+ *
+ * @access public
+ * @since 1.0
+ * @param array $element_attribute Element/attribute key/value pairs
+ */
+ function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
+ {
+ $this->sanitize->set_url_replacements($element_attribute);
+ }
+
+ /**
+ * Set the handler to enable the display of cached favicons.
+ *
+ * @access public
+ * @param str $page Web-accessible path to the handler_favicon.php file.
+ * @param str $qs The query string that the value should be passed to.
+ */
+ function set_favicon_handler($page = false, $qs = 'i')
+ {
+ if ($page != false)
+ {
+ $this->favicon_handler = $page . '?' . $qs . '=';
+ }
+ else
+ {
+ $this->favicon_handler = '';
+ }
+ }
+
+ /**
+ * Set the handler to enable the display of cached images.
+ *
+ * @access public
+ * @param str $page Web-accessible path to the handler_image.php file.
+ * @param str $qs The query string that the value should be passed to.
+ */
+ function set_image_handler($page = false, $qs = 'i')
+ {
+ if ($page != false)
+ {
+ $this->sanitize->set_image_handler($page . '?' . $qs . '=');
+ }
+ else
+ {
+ $this->image_handler = '';
+ }
+ }
+
+ /**
+ * Set the limit for items returned per-feed with multifeeds.
+ *
+ * @access public
+ * @param integer $limit The maximum number of items to return.
+ */
+ function set_item_limit($limit = 0)
+ {
+ $this->item_limit = (int) $limit;
+ }
+
+ function init()
+ {
+ if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
+ {
+ return false;
+ }
+ if (isset($_GET[$this->javascript]))
+ {
+ if (function_exists('ob_gzhandler'))
+ {
+ ob_start('ob_gzhandler');
+ }
+ header('Content-type: text/javascript; charset: UTF-8');
+ header('Cache-Control: must-revalidate');
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
+ ?>
+function embed_odeo(link) {
+ document.writeln('');
+}
+
+function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
+ if (placeholder != '') {
+ document.writeln('');
+ }
+ else {
+ document.writeln('');
+ }
+}
+
+function embed_flash(bgcolor, width, height, link, loop, type) {
+ document.writeln('');
+}
+
+function embed_flv(width, height, link, placeholder, loop, player) {
+ document.writeln('');
+}
+
+function embed_wmedia(width, height, link) {
+ document.writeln('');
+}
+ sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
+ $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
+
+ if ($this->feed_url !== null || $this->raw_data !== null)
+ {
+ $this->data = array();
+ $this->multifeed_objects = array();
+ $cache = false;
+
+ if ($this->feed_url !== null)
+ {
+ $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
+ // Decide whether to enable caching
+ if ($this->cache && $parsed_feed_url['scheme'] !== '')
+ {
+ $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
+ }
+ // If it's enabled and we don't want an XML dump, use the cache
+ if ($cache && !$this->xml_dump)
+ {
+ // Load the Cache
+ $this->data = $cache->load();
+ if (!empty($this->data))
+ {
+ // If the cache is for an outdated build of SimplePie
+ if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
+ {
+ $cache->unlink();
+ $this->data = array();
+ }
+ // If we've hit a collision just rerun it with caching disabled
+ elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
+ {
+ $cache = false;
+ $this->data = array();
+ }
+ // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
+ elseif (isset($this->data['feed_url']))
+ {
+ // If the autodiscovery cache is still valid use it.
+ if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
+ {
+ // Do not need to do feed autodiscovery yet.
+ if ($this->data['feed_url'] == $this->data['url'])
+ {
+ $cache->unlink();
+ $this->data = array();
+ }
+ else
+ {
+ $this->set_feed_url($this->data['feed_url']);
+ return $this->init();
+ }
+ }
+ }
+ // Check if the cache has been updated
+ elseif ($cache->mtime() + $this->cache_duration < time())
+ {
+ // If we have last-modified and/or etag set
+ if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
+ {
+ $headers = array();
+ if (isset($this->data['headers']['last-modified']))
+ {
+ $headers['if-modified-since'] = $this->data['headers']['last-modified'];
+ }
+ if (isset($this->data['headers']['etag']))
+ {
+ $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
+ }
+ $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
+ if ($file->success)
+ {
+ if ($file->status_code == 304)
+ {
+ $cache->touch();
+ return true;
+ }
+ else
+ {
+ $headers = $file->headers;
+ }
+ }
+ else
+ {
+ unset($file);
+ }
+ }
+ }
+ // If the cache is still valid, just return true
+ else
+ {
+ return true;
+ }
+ }
+ // If the cache is empty, delete it
+ else
+ {
+ $cache->unlink();
+ $this->data = array();
+ }
+ }
+ // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
+ if (!isset($file))
+ {
+ if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
+ {
+ $file =& $this->file;
+ }
+ else
+ {
+ $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
+ }
+ }
+ // If the file connection has an error, set SimplePie::error to that and quit
+ if (!$file->success)
+ {
+ $this->error = $file->error;
+ if (!empty($this->data))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (!$this->force_feed)
+ {
+ // Check if the supplied URL is a feed, if it isn't, look for it.
+ $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
+ if (!$locate->is_feed($file))
+ {
+ // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
+ unset($file);
+ if ($file = $locate->find($this->autodiscovery))
+ {
+ if ($cache)
+ {
+ $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
+ if (!$cache->save($this))
+ {
+ trigger_error("$cache->name is not writeable", E_USER_WARNING);
+ }
+ $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
+ }
+ $this->feed_url = $file->url;
+ }
+ else
+ {
+ $this->error = "A feed could not be found at $this->feed_url";
+ SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
+ return false;
+ }
+ }
+ $locate = null;
+ }
+
+ $headers = $file->headers;
+ $data = $file->body;
+ $sniffer = new $this->content_type_sniffer_class($file);
+ $sniffed = $sniffer->get_type();
+ }
+ else
+ {
+ $data = $this->raw_data;
+ }
+
+ // Set up array of possible encodings
+ $encodings = array();
+
+ // First check to see if input has been overridden.
+ if ($this->input_encoding !== false)
+ {
+ $encodings[] = $this->input_encoding;
+ }
+
+ $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
+ $text_types = array('text/xml', 'text/xml-external-parsed-entity');
+
+ // RFC 3023 (only applies to sniffed content)
+ if (isset($sniffed))
+ {
+ if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
+ {
+ if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
+ {
+ $encodings[] = strtoupper($charset[1]);
+ }
+ $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
+ $encodings[] = 'UTF-8';
+ }
+ elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
+ {
+ if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
+ {
+ $encodings[] = $charset[1];
+ }
+ $encodings[] = 'US-ASCII';
+ }
+ // Text MIME-type default
+ elseif (substr($sniffed, 0, 5) === 'text/')
+ {
+ $encodings[] = 'US-ASCII';
+ }
+ }
+
+ // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
+ $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
+ $encodings[] = 'UTF-8';
+ $encodings[] = 'ISO-8859-1';
+
+ // There's no point in trying an encoding twice
+ $encodings = array_unique($encodings);
+
+ // If we want the XML, just output that with the most likely encoding and quit
+ if ($this->xml_dump)
+ {
+ header('Content-type: text/xml; charset=' . $encodings[0]);
+ echo $data;
+ exit;
+ }
+
+ // Loop through each possible encoding, till we return something, or run out of possibilities
+ foreach ($encodings as $encoding)
+ {
+ // Change the encoding to UTF-8 (as we always use UTF-8 internally)
+ $utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
+
+ // Create new parser
+ $parser =& new $this->parser_class();
+
+ // If it's parsed fine
+ if ($parser->parse($utf8_data, 'UTF-8'))
+ {
+ $this->data = $parser->get_data();
+ if (isset($this->data['child']))
+ {
+ if (isset($headers))
+ {
+ $this->data['headers'] = $headers;
+ }
+ $this->data['build'] = SIMPLEPIE_BUILD;
+
+ // Cache the file if caching is enabled
+ if ($cache && !$cache->save($this))
+ {
+ trigger_error("$cache->name is not writeable", E_USER_WARNING);
+ }
+ return true;
+ }
+ else
+ {
+ $this->error = "A feed could not be found at $this->feed_url";
+ SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
+ return false;
+ }
+ }
+ }
+ // We have an error, just set SimplePie::error to it and quit
+ $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
+ SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
+ return false;
+ }
+ elseif (!empty($this->multifeed_url))
+ {
+ $i = 0;
+ $success = 0;
+ $this->multifeed_objects = array();
+ foreach ($this->multifeed_url as $url)
+ {
+ if (SIMPLEPIE_PHP5)
+ {
+ // This keyword needs to defy coding standards for PHP4 compatibility
+ $this->multifeed_objects[$i] = clone($this);
+ }
+ else
+ {
+ $this->multifeed_objects[$i] = $this;
+ }
+ $this->multifeed_objects[$i]->set_feed_url($url);
+ $success |= $this->multifeed_objects[$i]->init();
+ $i++;
+ }
+ return (bool) $success;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Return the error message for the occured error
+ *
+ * @access public
+ * @return string Error message
+ */
+ function error()
+ {
+ return $this->error;
+ }
+
+ function get_encoding()
+ {
+ return $this->sanitize->output_encoding;
+ }
+
+ function handle_content_type($mime = 'text/html')
+ {
+ if (!headers_sent())
+ {
+ $header = "Content-type: $mime;";
+ if ($this->get_encoding())
+ {
+ $header .= ' charset=' . $this->get_encoding();
+ }
+ else
+ {
+ $header .= ' charset=UTF-8';
+ }
+ header($header);
+ }
+ }
+
+ function get_type()
+ {
+ if (!isset($this->data['type']))
+ {
+ $this->data['type'] = SIMPLEPIE_TYPE_ALL;
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
+ {
+ $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
+ {
+ $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
+ {
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
+ {
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
+ }
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
+ {
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
+ }
+ }
+ elseif (isset($this->data['child']['']['rss']))
+ {
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
+ if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
+ {
+ switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
+ {
+ case '0.91':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
+ if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
+ {
+ switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
+ {
+ case '0':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
+ break;
+
+ case '24':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
+ break;
+ }
+ }
+ break;
+
+ case '0.92':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
+ break;
+
+ case '0.93':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
+ break;
+
+ case '0.94':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
+ break;
+
+ case '2.0':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
+ break;
+ }
+ }
+ }
+ else
+ {
+ $this->data['type'] = SIMPLEPIE_TYPE_NONE;
+ }
+ }
+ return $this->data['type'];
+ }
+
+ /**
+ * Returns the URL for the favicon of the feed's website.
+ *
+ * @todo Cache atom:icon
+ * @access public
+ * @since 1.0
+ */
+ function get_favicon()
+ {
+ //chopped out a bit here because I always want to use the domain default favicon, not the one set in the feed
+ if (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
+ {
+ $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
+
+ if ($this->cache && $this->favicon_handler)
+ {
+ $favicon_filename = call_user_func($this->cache_name_function, $favicon);
+ $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
+
+ if ($cache->load())
+ {
+ return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
+
+ if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
+ {
+ $sniffer = new $this->content_type_sniffer_class($file);
+ if (substr($sniffer->get_type(), 0, 6) === 'image/')
+ {
+ if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
+ {
+ return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ trigger_error("$cache->name is not writeable", E_USER_WARNING);
+ return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @todo If we have a perm redirect we should return the new URL
+ * @todo When we make the above change, let's support as well
+ * @todo Also, |atom:link|@rel=self
+ */
+ function subscribe_url()
+ {
+ if ($this->feed_url !== null)
+ {
+ return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function subscribe_feed()
+ {
+ if ($this->feed_url !== null)
+ {
+ return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function subscribe_outlook()
+ {
+ if ($this->feed_url !== null)
+ {
+ return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function subscribe_podcast()
+ {
+ if ($this->feed_url !== null)
+ {
+ return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function subscribe_itunes()
+ {
+ if ($this->feed_url !== null)
+ {
+ return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Creates the subscribe_* methods' return data
+ *
+ * @access private
+ * @param string $feed_url String to prefix to the feed URL
+ * @param string $site_url String to prefix to the site URL (and
+ * suffix to the feed URL)
+ * @return mixed URL if feed exists, false otherwise
+ */
+ function subscribe_service($feed_url, $site_url = null)
+ {
+ if ($this->subscribe_url())
+ {
+ $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
+ if ($site_url !== null && $this->get_link() !== null)
+ {
+ $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
+ }
+ return $return;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function subscribe_aol()
+ {
+ return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
+ }
+
+ function subscribe_bloglines()
+ {
+ return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
+ }
+
+ function subscribe_eskobo()
+ {
+ return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
+ }
+
+ function subscribe_feedfeeds()
+ {
+ return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
+ }
+
+ function subscribe_feedster()
+ {
+ return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
+ }
+
+ function subscribe_google()
+ {
+ return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
+ }
+
+ function subscribe_gritwire()
+ {
+ return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
+ }
+
+ function subscribe_msn()
+ {
+ return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
+ }
+
+ function subscribe_netvibes()
+ {
+ return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
+ }
+
+ function subscribe_newsburst()
+ {
+ return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
+ }
+
+ function subscribe_newsgator()
+ {
+ return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
+ }
+
+ function subscribe_odeo()
+ {
+ return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
+ }
+
+ function subscribe_podnova()
+ {
+ return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
+ }
+
+ function subscribe_rojo()
+ {
+ return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
+ }
+
+ function subscribe_yahoo()
+ {
+ return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
+ }
+
+ function get_feed_tags($namespace, $tag)
+ {
+ $type = $this->get_type();
+ if ($type & SIMPLEPIE_TYPE_ATOM_10)
+ {
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_ATOM_03)
+ {
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_RDF)
+ {
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
+ {
+ if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
+ {
+ return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
+ }
+ }
+ return null;
+ }
+
+ function get_channel_tags($namespace, $tag)
+ {
+ $type = $this->get_type();
+ if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
+ {
+ if ($return = $this->get_feed_tags($namespace, $tag))
+ {
+ return $return;
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_10)
+ {
+ if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
+ {
+ if (isset($channel[0]['child'][$namespace][$tag]))
+ {
+ return $channel[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_090)
+ {
+ if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
+ {
+ if (isset($channel[0]['child'][$namespace][$tag]))
+ {
+ return $channel[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
+ {
+ if ($channel = $this->get_feed_tags('', 'channel'))
+ {
+ if (isset($channel[0]['child'][$namespace][$tag]))
+ {
+ return $channel[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ return null;
+ }
+
+ function get_image_tags($namespace, $tag)
+ {
+ $type = $this->get_type();
+ if ($type & SIMPLEPIE_TYPE_RSS_10)
+ {
+ if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
+ {
+ if (isset($image[0]['child'][$namespace][$tag]))
+ {
+ return $image[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_090)
+ {
+ if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
+ {
+ if (isset($image[0]['child'][$namespace][$tag]))
+ {
+ return $image[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
+ {
+ if ($image = $this->get_channel_tags('', 'image'))
+ {
+ if (isset($image[0]['child'][$namespace][$tag]))
+ {
+ return $image[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ return null;
+ }
+
+ function get_base($element = array())
+ {
+ if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
+ {
+ return $element['xml_base'];
+ }
+ elseif ($this->get_link() !== null)
+ {
+ return $this->get_link();
+ }
+ else
+ {
+ return $this->subscribe_url();
+ }
+ }
+
+ function sanitize($data, $type, $base = '')
+ {
+ return $this->sanitize->sanitize($data, $type, $base);
+ }
+
+ function get_title()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags('', 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_categories()
+ {
+ $categories = array();
+
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['attribs']['']['term']))
+ {
+ $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] =& new $this->category_class($term, $scheme, $label);
+ }
+ foreach ((array) $this->get_channel_tags('', 'category') as $category)
+ {
+ $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
+ {
+ $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
+ {
+ $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($categories))
+ {
+ return SimplePie_Misc::array_unique($categories);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_author($key = 0)
+ {
+ $authors = $this->get_authors();
+ if (isset($authors[$key]))
+ {
+ return $authors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_authors()
+ {
+ $authors = array();
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $authors[] =& new $this->author_class($name, $uri, $email);
+ }
+ }
+ if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $authors[] =& new $this->author_class($name, $url, $email);
+ }
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
+ {
+ $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
+ {
+ $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
+ {
+ $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($authors))
+ {
+ return SimplePie_Misc::array_unique($authors);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_contributor($key = 0)
+ {
+ $contributors = $this->get_contributors();
+ if (isset($contributors[$key]))
+ {
+ return $contributors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_contributors()
+ {
+ $contributors = array();
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $contributors[] =& new $this->author_class($name, $uri, $email);
+ }
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $contributors[] =& new $this->author_class($name, $url, $email);
+ }
+ }
+
+ if (!empty($contributors))
+ {
+ return SimplePie_Misc::array_unique($contributors);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_link($key = 0, $rel = 'alternate')
+ {
+ $links = $this->get_links($rel);
+ if (isset($links[$key]))
+ {
+ return $links[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Added for parity between the parent-level and the item/entry-level.
+ */
+ function get_permalink()
+ {
+ return $this->get_link(0);
+ }
+
+ function get_links($rel = 'alternate')
+ {
+ if (!isset($this->data['links']))
+ {
+ $this->data['links'] = array();
+ if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
+ {
+ foreach ($links as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+ }
+ }
+ }
+ if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
+ {
+ foreach ($links as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+
+ }
+ }
+ }
+ if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_channel_tags('', 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+
+ $keys = array_keys($this->data['links']);
+ foreach ($keys as $key)
+ {
+ if (SimplePie_Misc::is_isegment_nz_nc($key))
+ {
+ if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
+ $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
+ }
+ else
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
+ }
+ }
+ elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
+ {
+ $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
+ }
+ $this->data['links'][$key] = array_unique($this->data['links'][$key]);
+ }
+ }
+
+ if (isset($this->data['links'][$rel]))
+ {
+ return $this->data['links'][$rel];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_description()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags('', 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_copyright()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags('', 'copyright'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_language()
+ {
+ if ($return = $this->get_channel_tags('', 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
+ {
+ return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
+ {
+ return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
+ {
+ return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['headers']['content-language']))
+ {
+ return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_latitude()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
+ {
+ return (float) $match[1];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_longitude()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
+ {
+ return (float) $match[2];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_image_title()
+ {
+ if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_image_tags('', 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_image_url()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
+ {
+ return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_image_tags('', 'url'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_image_link()
+ {
+ if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_image_tags('', 'link'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_image_width()
+ {
+ if ($return = $this->get_image_tags('', 'width'))
+ {
+ return round($return[0]['data']);
+ }
+ elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
+ {
+ return 88.0;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_image_height()
+ {
+ if ($return = $this->get_image_tags('', 'height'))
+ {
+ return round($return[0]['data']);
+ }
+ elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
+ {
+ return 31.0;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_item_quantity($max = 0)
+ {
+ $qty = count($this->get_items());
+ if ($max == 0)
+ {
+ return $qty;
+ }
+ else
+ {
+ return ($qty > $max) ? $max : $qty;
+ }
+ }
+
+ function get_item($key = 0)
+ {
+ $items = $this->get_items();
+ if (isset($items[$key]))
+ {
+ return $items[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_items($start = 0, $end = 0)
+ {
+ if (!empty($this->multifeed_objects))
+ {
+ return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
+ }
+ elseif (!isset($this->data['items']))
+ {
+ if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
+ {
+ $keys = array_keys($items);
+ foreach ($keys as $key)
+ {
+ $this->data['items'][] =& new $this->item_class($this, $items[$key]);
+ }
+ }
+ if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
+ {
+ $keys = array_keys($items);
+ foreach ($keys as $key)
+ {
+ $this->data['items'][] =& new $this->item_class($this, $items[$key]);
+ }
+ }
+ if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
+ {
+ $keys = array_keys($items);
+ foreach ($keys as $key)
+ {
+ $this->data['items'][] =& new $this->item_class($this, $items[$key]);
+ }
+ }
+ if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
+ {
+ $keys = array_keys($items);
+ foreach ($keys as $key)
+ {
+ $this->data['items'][] =& new $this->item_class($this, $items[$key]);
+ }
+ }
+ if ($items = $this->get_channel_tags('', 'item'))
+ {
+ $keys = array_keys($items);
+ foreach ($keys as $key)
+ {
+ $this->data['items'][] =& new $this->item_class($this, $items[$key]);
+ }
+ }
+ }
+
+ if (!empty($this->data['items']))
+ {
+ // If we want to order it by date, check if all items have a date, and then sort it
+ if ($this->order_by_date)
+ {
+ if (!isset($this->data['ordered_items']))
+ {
+ $do_sort = true;
+ foreach ($this->data['items'] as $item)
+ {
+ if (!$item->get_date('U'))
+ {
+ $do_sort = false;
+ break;
+ }
+ }
+ $item = null;
+ $this->data['ordered_items'] = $this->data['items'];
+ if ($do_sort)
+ {
+ usort($this->data['ordered_items'], array(&$this, 'sort_items'));
+ }
+ }
+ $items = $this->data['ordered_items'];
+ }
+ else
+ {
+ $items = $this->data['items'];
+ }
+
+ // Slice the data as desired
+ if ($end == 0)
+ {
+ return array_slice($items, $start);
+ }
+ else
+ {
+ return array_slice($items, $start, $end);
+ }
+ }
+ else
+ {
+ return array();
+ }
+ }
+
+ function sort_items($a, $b)
+ {
+ return $a->get_date('U') <= $b->get_date('U');
+ }
+
+ function merge_items($urls, $start = 0, $end = 0, $limit = 0)
+ {
+ if (is_array($urls) && sizeof($urls) > 0)
+ {
+ $items = array();
+ foreach ($urls as $arg)
+ {
+ if (is_a($arg, 'SimplePie'))
+ {
+ $items = array_merge($items, $arg->get_items(0, $limit));
+ }
+ else
+ {
+ trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
+ }
+ }
+
+ $do_sort = true;
+ foreach ($items as $item)
+ {
+ if (!$item->get_date('U'))
+ {
+ $do_sort = false;
+ break;
+ }
+ }
+ $item = null;
+ if ($do_sort)
+ {
+ usort($items, array('SimplePie', 'sort_items'));
+ }
+
+ if ($end == 0)
+ {
+ return array_slice($items, $start);
+ }
+ else
+ {
+ return array_slice($items, $start, $end);
+ }
+ }
+ else
+ {
+ trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
+ return array();
+ }
+ }
+}
+
+class SimplePie_Item
+{
+ var $feed;
+ var $data = array();
+
+ function SimplePie_Item($feed, $data)
+ {
+ $this->feed = $feed;
+ $this->data = $data;
+ }
+
+ function __toString()
+ {
+ return md5(serialize($this->data));
+ }
+
+ /**
+ * Remove items that link back to this before destroying this object
+ */
+ function __destruct()
+ {
+ unset($this->feed);
+ }
+
+ function get_item_tags($namespace, $tag)
+ {
+ if (isset($this->data['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][$namespace][$tag];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_base($element = array())
+ {
+ return $this->feed->get_base($element);
+ }
+
+ function sanitize($data, $type, $base = '')
+ {
+ return $this->feed->sanitize($data, $type, $base);
+ }
+
+ function get_feed()
+ {
+ return $this->feed;
+ }
+
+ function get_id($hash = false)
+ {
+ if (!$hash)
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags('', 'guid'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (($return = $this->get_permalink()) !== null)
+ {
+ return $return;
+ }
+ elseif (($return = $this->get_title()) !== null)
+ {
+ return $return;
+ }
+ }
+ if ($this->get_permalink() !== null || $this->get_title() !== null)
+ {
+ return md5($this->get_permalink() . $this->get_title());
+ }
+ else
+ {
+ return md5(serialize($this->data));
+ }
+ }
+
+ function get_title()
+ {
+ if (!isset($this->data['title']))
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags('', 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $this->data['title'] = null;
+ }
+ }
+ return $this->data['title'];
+ }
+
+ function get_description($description_only = false)
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags('', 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (!$description_only)
+ {
+ return $this->get_content(true);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_content($content_only = false)
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif (!$content_only)
+ {
+ return $this->get_description(true);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_categories()
+ {
+ $categories = array();
+
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['attribs']['']['term']))
+ {
+ $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] =& new $this->feed->category_class($term, $scheme, $label);
+ }
+ foreach ((array) $this->get_item_tags('', 'category') as $category)
+ {
+ $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
+ {
+ $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
+ {
+ $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($categories))
+ {
+ return SimplePie_Misc::array_unique($categories);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_author($key = 0)
+ {
+ $authors = $this->get_authors();
+ if (isset($authors[$key]))
+ {
+ return $authors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_contributor($key = 0)
+ {
+ $contributors = $this->get_contributors();
+ if (isset($contributors[$key]))
+ {
+ return $contributors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_contributors()
+ {
+ $contributors = array();
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $contributors[] =& new $this->feed->author_class($name, $uri, $email);
+ }
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $contributors[] =& new $this->feed->author_class($name, $url, $email);
+ }
+ }
+
+ if (!empty($contributors))
+ {
+ return SimplePie_Misc::array_unique($contributors);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * @todo Atom inheritance (item author, source author, feed author)
+ */
+ function get_authors()
+ {
+ $authors = array();
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $authors[] =& new $this->feed->author_class($name, $uri, $email);
+ }
+ }
+ if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $authors[] =& new $this->feed->author_class($name, $url, $email);
+ }
+ }
+ if ($author = $this->get_item_tags('', 'author'))
+ {
+ $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
+ {
+ $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
+ {
+ $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
+ {
+ $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($authors))
+ {
+ return SimplePie_Misc::array_unique($authors);
+ }
+ elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
+ {
+ return $authors;
+ }
+ elseif ($authors = $this->feed->get_authors())
+ {
+ return $authors;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_copyright()
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_date($date_format = 'j F Y, g:i a')
+ {
+ if (!isset($this->data['date']))
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags('', 'pubDate'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+
+ if (!empty($this->data['date']['raw']))
+ {
+ $parser = SimplePie_Parse_Date::get();
+ $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
+ }
+ else
+ {
+ $this->data['date'] = null;
+ }
+ }
+ if ($this->data['date'])
+ {
+ $date_format = (string) $date_format;
+ switch ($date_format)
+ {
+ case '':
+ return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
+
+ case 'U':
+ return $this->data['date']['parsed'];
+
+ default:
+ return date($date_format, $this->data['date']['parsed']);
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_local_date($date_format = '%c')
+ {
+ if (!$date_format)
+ {
+ return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (($date = $this->get_date('U')) !== null)
+ {
+ return strftime($date_format, $date);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_permalink()
+ {
+ $link = $this->get_link();
+ $enclosure = $this->get_enclosure(0);
+ if ($link !== null)
+ {
+ return $link;
+ }
+ elseif ($enclosure !== null)
+ {
+ return $enclosure->get_link();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_link($key = 0, $rel = 'alternate')
+ {
+ $links = $this->get_links($rel);
+ if ($links[$key] !== null)
+ {
+ return $links[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_links($rel = 'alternate')
+ {
+ if (!isset($this->data['links']))
+ {
+ $this->data['links'] = array();
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+
+ }
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+ }
+ }
+ if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_item_tags('', 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_item_tags('', 'guid'))
+ {
+ if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ }
+
+ $keys = array_keys($this->data['links']);
+ foreach ($keys as $key)
+ {
+ if (SimplePie_Misc::is_isegment_nz_nc($key))
+ {
+ if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
+ $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
+ }
+ else
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
+ }
+ }
+ elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
+ {
+ $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
+ }
+ $this->data['links'][$key] = array_unique($this->data['links'][$key]);
+ }
+ }
+ if (isset($this->data['links'][$rel]))
+ {
+ return $this->data['links'][$rel];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * @todo Add ability to prefer one type of content over another (in a media group).
+ */
+ function get_enclosure($key = 0, $prefer = null)
+ {
+ $enclosures = $this->get_enclosures();
+ if (isset($enclosures[$key]))
+ {
+ return $enclosures[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Grabs all available enclosures (podcasts, etc.)
+ *
+ * Supports the RSS tag, as well as Media RSS and iTunes RSS.
+ *
+ * At this point, we're pretty much assuming that all enclosures for an item are the same content. Anything else is too complicated to properly support.
+ *
+ * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
+ * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists).
+ */
+ function get_enclosures()
+ {
+ if (!isset($this->data['enclosures']))
+ {
+ $this->data['enclosures'] = array();
+
+ // Elements
+ $captions_parent = null;
+ $categories_parent = null;
+ $copyrights_parent = null;
+ $credits_parent = null;
+ $description_parent = null;
+ $duration_parent = null;
+ $hashes_parent = null;
+ $keywords_parent = null;
+ $player_parent = null;
+ $ratings_parent = null;
+ $restrictions_parent = null;
+ $thumbnails_parent = null;
+ $title_parent = null;
+
+ // Let's do the channel and item-level ones first, and just re-use them if we need to.
+ $parent = $this->get_feed();
+
+ // CAPTIONS
+ if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
+ {
+ foreach ($captions as $caption)
+ {
+ $caption_type = null;
+ $caption_lang = null;
+ $caption_startTime = null;
+ $caption_endTime = null;
+ $caption_text = null;
+ if (isset($caption['attribs']['']['type']))
+ {
+ $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['lang']))
+ {
+ $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['start']))
+ {
+ $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['end']))
+ {
+ $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['data']))
+ {
+ $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
+ }
+ }
+ elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
+ {
+ foreach ($captions as $caption)
+ {
+ $caption_type = null;
+ $caption_lang = null;
+ $caption_startTime = null;
+ $caption_endTime = null;
+ $caption_text = null;
+ if (isset($caption['attribs']['']['type']))
+ {
+ $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['lang']))
+ {
+ $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['start']))
+ {
+ $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['end']))
+ {
+ $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['data']))
+ {
+ $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
+ }
+ }
+ if (is_array($captions_parent))
+ {
+ $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
+ }
+
+ // CATEGORIES
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['data']))
+ {
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = 'http://search.yahoo.com/mrss/category_schema';
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
+ }
+ foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['data']))
+ {
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = 'http://search.yahoo.com/mrss/category_schema';
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
+ }
+ foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
+ {
+ $term = null;
+ $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
+ $label = null;
+ if (isset($category['attribs']['']['text']))
+ {
+ $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
+
+ if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
+ {
+ foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
+ {
+ if (isset($subcategory['attribs']['']['text']))
+ {
+ $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
+ }
+ }
+ }
+ if (is_array($categories_parent))
+ {
+ $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
+ }
+
+ // COPYRIGHT
+ if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
+ {
+ $copyright_url = null;
+ $copyright_label = null;
+ if (isset($copyright[0]['attribs']['']['url']))
+ {
+ $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($copyright[0]['data']))
+ {
+ $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
+ }
+ elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
+ {
+ $copyright_url = null;
+ $copyright_label = null;
+ if (isset($copyright[0]['attribs']['']['url']))
+ {
+ $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($copyright[0]['data']))
+ {
+ $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
+ }
+
+ // CREDITS
+ if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
+ {
+ foreach ($credits as $credit)
+ {
+ $credit_role = null;
+ $credit_scheme = null;
+ $credit_name = null;
+ if (isset($credit['attribs']['']['role']))
+ {
+ $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($credit['attribs']['']['scheme']))
+ {
+ $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $credit_scheme = 'urn:ebu';
+ }
+ if (isset($credit['data']))
+ {
+ $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
+ }
+ }
+ elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
+ {
+ foreach ($credits as $credit)
+ {
+ $credit_role = null;
+ $credit_scheme = null;
+ $credit_name = null;
+ if (isset($credit['attribs']['']['role']))
+ {
+ $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($credit['attribs']['']['scheme']))
+ {
+ $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $credit_scheme = 'urn:ebu';
+ }
+ if (isset($credit['data']))
+ {
+ $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
+ }
+ }
+ if (is_array($credits_parent))
+ {
+ $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
+ }
+
+ // DESCRIPTION
+ if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
+ {
+ if (isset($description_parent[0]['data']))
+ {
+ $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ }
+ elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
+ {
+ if (isset($description_parent[0]['data']))
+ {
+ $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ }
+
+ // DURATION
+ if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
+ {
+ $seconds = null;
+ $minutes = null;
+ $hours = null;
+ if (isset($duration_parent[0]['data']))
+ {
+ $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ if (sizeof($temp) > 0)
+ {
+ (int) $seconds = array_pop($temp);
+ }
+ if (sizeof($temp) > 0)
+ {
+ (int) $minutes = array_pop($temp);
+ $seconds += $minutes * 60;
+ }
+ if (sizeof($temp) > 0)
+ {
+ (int) $hours = array_pop($temp);
+ $seconds += $hours * 3600;
+ }
+ unset($temp);
+ $duration_parent = $seconds;
+ }
+ }
+
+ // HASHES
+ if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
+ {
+ foreach ($hashes_iterator as $hash)
+ {
+ $value = null;
+ $algo = null;
+ if (isset($hash['data']))
+ {
+ $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($hash['attribs']['']['algo']))
+ {
+ $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $algo = 'md5';
+ }
+ $hashes_parent[] = $algo.':'.$value;
+ }
+ }
+ elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
+ {
+ foreach ($hashes_iterator as $hash)
+ {
+ $value = null;
+ $algo = null;
+ if (isset($hash['data']))
+ {
+ $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($hash['attribs']['']['algo']))
+ {
+ $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $algo = 'md5';
+ }
+ $hashes_parent[] = $algo.':'.$value;
+ }
+ }
+ if (is_array($hashes_parent))
+ {
+ $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
+ }
+
+ // KEYWORDS
+ if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
+ {
+ if (isset($keywords[0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords_parent[] = trim($word);
+ }
+ }
+ unset($temp);
+ }
+ elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
+ {
+ if (isset($keywords[0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords_parent[] = trim($word);
+ }
+ }
+ unset($temp);
+ }
+ elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
+ {
+ if (isset($keywords[0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords_parent[] = trim($word);
+ }
+ }
+ unset($temp);
+ }
+ elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
+ {
+ if (isset($keywords[0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords_parent[] = trim($word);
+ }
+ }
+ unset($temp);
+ }
+ if (is_array($keywords_parent))
+ {
+ $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
+ }
+
+ // PLAYER
+ if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
+ {
+ if (isset($player_parent[0]['attribs']['']['url']))
+ {
+ $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
+ {
+ if (isset($player_parent[0]['attribs']['']['url']))
+ {
+ $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+
+ // RATINGS
+ if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
+ {
+ foreach ($ratings as $rating)
+ {
+ $rating_scheme = null;
+ $rating_value = null;
+ if (isset($rating['attribs']['']['scheme']))
+ {
+ $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $rating_scheme = 'urn:simple';
+ }
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ }
+ elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
+ {
+ foreach ($ratings as $rating)
+ {
+ $rating_scheme = 'urn:itunes';
+ $rating_value = null;
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ }
+ elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
+ {
+ foreach ($ratings as $rating)
+ {
+ $rating_scheme = null;
+ $rating_value = null;
+ if (isset($rating['attribs']['']['scheme']))
+ {
+ $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $rating_scheme = 'urn:simple';
+ }
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ }
+ elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
+ {
+ foreach ($ratings as $rating)
+ {
+ $rating_scheme = 'urn:itunes';
+ $rating_value = null;
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ }
+ if (is_array($ratings_parent))
+ {
+ $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
+ }
+
+ // RESTRICTIONS
+ if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
+ {
+ foreach ($restrictions as $restriction)
+ {
+ $restriction_relationship = null;
+ $restriction_type = null;
+ $restriction_value = null;
+ if (isset($restriction['attribs']['']['relationship']))
+ {
+ $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['attribs']['']['type']))
+ {
+ $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['data']))
+ {
+ $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ }
+ elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
+ {
+ foreach ($restrictions as $restriction)
+ {
+ $restriction_relationship = 'allow';
+ $restriction_type = null;
+ $restriction_value = 'itunes';
+ if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
+ {
+ $restriction_relationship = 'deny';
+ }
+ $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ }
+ elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
+ {
+ foreach ($restrictions as $restriction)
+ {
+ $restriction_relationship = null;
+ $restriction_type = null;
+ $restriction_value = null;
+ if (isset($restriction['attribs']['']['relationship']))
+ {
+ $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['attribs']['']['type']))
+ {
+ $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['data']))
+ {
+ $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ }
+ elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
+ {
+ foreach ($restrictions as $restriction)
+ {
+ $restriction_relationship = 'allow';
+ $restriction_type = null;
+ $restriction_value = 'itunes';
+ if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
+ {
+ $restriction_relationship = 'deny';
+ }
+ $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ }
+ if (is_array($restrictions_parent))
+ {
+ $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
+ }
+
+ // THUMBNAILS
+ if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
+ {
+ foreach ($thumbnails as $thumbnail)
+ {
+ if (isset($thumbnail['attribs']['']['url']))
+ {
+ $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ }
+ elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
+ {
+ foreach ($thumbnails as $thumbnail)
+ {
+ if (isset($thumbnail['attribs']['']['url']))
+ {
+ $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ }
+
+ // TITLES
+ if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
+ {
+ if (isset($title_parent[0]['data']))
+ {
+ $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ }
+ elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
+ {
+ if (isset($title_parent[0]['data']))
+ {
+ $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ }
+
+ // Clear the memory
+ unset($parent);
+
+ // If we have media:group tags, loop through them.
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
+ {
+ // If we have media:content tags, loop through them.
+ foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
+ {
+ if (isset($content['attribs']['']['url']))
+ {
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ // Elements
+ $captions = null;
+ $categories = null;
+ $copyrights = null;
+ $credits = null;
+ $description = null;
+ $hashes = null;
+ $keywords = null;
+ $player = null;
+ $ratings = null;
+ $restrictions = null;
+ $thumbnails = null;
+ $title = null;
+
+ // Start checking the attributes of media:content
+ if (isset($content['attribs']['']['bitrate']))
+ {
+ $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['channels']))
+ {
+ $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['duration']))
+ {
+ $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $duration = $duration_parent;
+ }
+ if (isset($content['attribs']['']['expression']))
+ {
+ $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['framerate']))
+ {
+ $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['height']))
+ {
+ $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['lang']))
+ {
+ $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['fileSize']))
+ {
+ $length = ceil($content['attribs']['']['fileSize']);
+ }
+ if (isset($content['attribs']['']['medium']))
+ {
+ $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['samplingrate']))
+ {
+ $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['type']))
+ {
+ $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['width']))
+ {
+ $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+
+ // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
+
+ // CAPTIONS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
+ {
+ $caption_type = null;
+ $caption_lang = null;
+ $caption_startTime = null;
+ $caption_endTime = null;
+ $caption_text = null;
+ if (isset($caption['attribs']['']['type']))
+ {
+ $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['lang']))
+ {
+ $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['start']))
+ {
+ $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['end']))
+ {
+ $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['data']))
+ {
+ $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
+ }
+ if (is_array($captions))
+ {
+ $captions = array_values(SimplePie_Misc::array_unique($captions));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
+ {
+ $caption_type = null;
+ $caption_lang = null;
+ $caption_startTime = null;
+ $caption_endTime = null;
+ $caption_text = null;
+ if (isset($caption['attribs']['']['type']))
+ {
+ $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['lang']))
+ {
+ $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['start']))
+ {
+ $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['end']))
+ {
+ $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['data']))
+ {
+ $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
+ }
+ if (is_array($captions))
+ {
+ $captions = array_values(SimplePie_Misc::array_unique($captions));
+ }
+ }
+ else
+ {
+ $captions = $captions_parent;
+ }
+
+ // CATEGORIES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
+ {
+ foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['data']))
+ {
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = 'http://search.yahoo.com/mrss/category_schema';
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] =& new $this->feed->category_class($term, $scheme, $label);
+ }
+ }
+ if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
+ {
+ foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['data']))
+ {
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = 'http://search.yahoo.com/mrss/category_schema';
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] =& new $this->feed->category_class($term, $scheme, $label);
+ }
+ }
+ if (is_array($categories) && is_array($categories_parent))
+ {
+ $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
+ }
+ elseif (is_array($categories))
+ {
+ $categories = array_values(SimplePie_Misc::array_unique($categories));
+ }
+ elseif (is_array($categories_parent))
+ {
+ $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
+ }
+
+ // COPYRIGHTS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
+ {
+ $copyright_url = null;
+ $copyright_label = null;
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
+ {
+ $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
+ {
+ $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
+ {
+ $copyright_url = null;
+ $copyright_label = null;
+ if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
+ {
+ $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
+ {
+ $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
+ }
+ else
+ {
+ $copyrights = $copyrights_parent;
+ }
+
+ // CREDITS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
+ {
+ $credit_role = null;
+ $credit_scheme = null;
+ $credit_name = null;
+ if (isset($credit['attribs']['']['role']))
+ {
+ $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($credit['attribs']['']['scheme']))
+ {
+ $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $credit_scheme = 'urn:ebu';
+ }
+ if (isset($credit['data']))
+ {
+ $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
+ }
+ if (is_array($credits))
+ {
+ $credits = array_values(SimplePie_Misc::array_unique($credits));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
+ {
+ $credit_role = null;
+ $credit_scheme = null;
+ $credit_name = null;
+ if (isset($credit['attribs']['']['role']))
+ {
+ $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($credit['attribs']['']['scheme']))
+ {
+ $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $credit_scheme = 'urn:ebu';
+ }
+ if (isset($credit['data']))
+ {
+ $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
+ }
+ if (is_array($credits))
+ {
+ $credits = array_values(SimplePie_Misc::array_unique($credits));
+ }
+ }
+ else
+ {
+ $credits = $credits_parent;
+ }
+
+ // DESCRIPTION
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
+ {
+ $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
+ {
+ $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $description = $description_parent;
+ }
+
+ // HASHES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
+ {
+ $value = null;
+ $algo = null;
+ if (isset($hash['data']))
+ {
+ $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($hash['attribs']['']['algo']))
+ {
+ $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $algo = 'md5';
+ }
+ $hashes[] = $algo.':'.$value;
+ }
+ if (is_array($hashes))
+ {
+ $hashes = array_values(SimplePie_Misc::array_unique($hashes));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
+ {
+ $value = null;
+ $algo = null;
+ if (isset($hash['data']))
+ {
+ $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($hash['attribs']['']['algo']))
+ {
+ $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $algo = 'md5';
+ }
+ $hashes[] = $algo.':'.$value;
+ }
+ if (is_array($hashes))
+ {
+ $hashes = array_values(SimplePie_Misc::array_unique($hashes));
+ }
+ }
+ else
+ {
+ $hashes = $hashes_parent;
+ }
+
+ // KEYWORDS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
+ {
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords[] = trim($word);
+ }
+ unset($temp);
+ }
+ if (is_array($keywords))
+ {
+ $keywords = array_values(SimplePie_Misc::array_unique($keywords));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
+ {
+ if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords[] = trim($word);
+ }
+ unset($temp);
+ }
+ if (is_array($keywords))
+ {
+ $keywords = array_values(SimplePie_Misc::array_unique($keywords));
+ }
+ }
+ else
+ {
+ $keywords = $keywords_parent;
+ }
+
+ // PLAYER
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
+ {
+ $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
+ {
+ $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ $player = $player_parent;
+ }
+
+ // RATINGS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
+ {
+ $rating_scheme = null;
+ $rating_value = null;
+ if (isset($rating['attribs']['']['scheme']))
+ {
+ $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $rating_scheme = 'urn:simple';
+ }
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ if (is_array($ratings))
+ {
+ $ratings = array_values(SimplePie_Misc::array_unique($ratings));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
+ {
+ $rating_scheme = null;
+ $rating_value = null;
+ if (isset($rating['attribs']['']['scheme']))
+ {
+ $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $rating_scheme = 'urn:simple';
+ }
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ if (is_array($ratings))
+ {
+ $ratings = array_values(SimplePie_Misc::array_unique($ratings));
+ }
+ }
+ else
+ {
+ $ratings = $ratings_parent;
+ }
+
+ // RESTRICTIONS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
+ {
+ $restriction_relationship = null;
+ $restriction_type = null;
+ $restriction_value = null;
+ if (isset($restriction['attribs']['']['relationship']))
+ {
+ $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['attribs']['']['type']))
+ {
+ $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['data']))
+ {
+ $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ if (is_array($restrictions))
+ {
+ $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
+ {
+ $restriction_relationship = null;
+ $restriction_type = null;
+ $restriction_value = null;
+ if (isset($restriction['attribs']['']['relationship']))
+ {
+ $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['attribs']['']['type']))
+ {
+ $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['data']))
+ {
+ $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ if (is_array($restrictions))
+ {
+ $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
+ }
+ }
+ else
+ {
+ $restrictions = $restrictions_parent;
+ }
+
+ // THUMBNAILS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
+ {
+ $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ if (is_array($thumbnails))
+ {
+ $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
+ {
+ $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ if (is_array($thumbnails))
+ {
+ $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
+ }
+ }
+ else
+ {
+ $thumbnails = $thumbnails_parent;
+ }
+
+ // TITLES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
+ {
+ $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
+ {
+ $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $title = $title_parent;
+ }
+
+ $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
+ }
+ }
+ }
+
+ // If we have standalone media:content tags, loop through them.
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
+ {
+ foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
+ {
+ if (isset($content['attribs']['']['url']))
+ {
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ // Elements
+ $captions = null;
+ $categories = null;
+ $copyrights = null;
+ $credits = null;
+ $description = null;
+ $hashes = null;
+ $keywords = null;
+ $player = null;
+ $ratings = null;
+ $restrictions = null;
+ $thumbnails = null;
+ $title = null;
+
+ // Start checking the attributes of media:content
+ if (isset($content['attribs']['']['bitrate']))
+ {
+ $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['channels']))
+ {
+ $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['duration']))
+ {
+ $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $duration = $duration_parent;
+ }
+ if (isset($content['attribs']['']['expression']))
+ {
+ $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['framerate']))
+ {
+ $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['height']))
+ {
+ $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['lang']))
+ {
+ $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['fileSize']))
+ {
+ $length = ceil($content['attribs']['']['fileSize']);
+ }
+ if (isset($content['attribs']['']['medium']))
+ {
+ $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['samplingrate']))
+ {
+ $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['type']))
+ {
+ $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['width']))
+ {
+ $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+
+ // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
+
+ // CAPTIONS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
+ {
+ $caption_type = null;
+ $caption_lang = null;
+ $caption_startTime = null;
+ $caption_endTime = null;
+ $caption_text = null;
+ if (isset($caption['attribs']['']['type']))
+ {
+ $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['lang']))
+ {
+ $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['start']))
+ {
+ $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['end']))
+ {
+ $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['data']))
+ {
+ $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
+ }
+ if (is_array($captions))
+ {
+ $captions = array_values(SimplePie_Misc::array_unique($captions));
+ }
+ }
+ else
+ {
+ $captions = $captions_parent;
+ }
+
+ // CATEGORIES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
+ {
+ foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['data']))
+ {
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = 'http://search.yahoo.com/mrss/category_schema';
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] =& new $this->feed->category_class($term, $scheme, $label);
+ }
+ }
+ if (is_array($categories) && is_array($categories_parent))
+ {
+ $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
+ }
+ elseif (is_array($categories))
+ {
+ $categories = array_values(SimplePie_Misc::array_unique($categories));
+ }
+ elseif (is_array($categories_parent))
+ {
+ $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
+ }
+ else
+ {
+ $categories = null;
+ }
+
+ // COPYRIGHTS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
+ {
+ $copyright_url = null;
+ $copyright_label = null;
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
+ {
+ $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
+ {
+ $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
+ }
+ else
+ {
+ $copyrights = $copyrights_parent;
+ }
+
+ // CREDITS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
+ {
+ $credit_role = null;
+ $credit_scheme = null;
+ $credit_name = null;
+ if (isset($credit['attribs']['']['role']))
+ {
+ $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($credit['attribs']['']['scheme']))
+ {
+ $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $credit_scheme = 'urn:ebu';
+ }
+ if (isset($credit['data']))
+ {
+ $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
+ }
+ if (is_array($credits))
+ {
+ $credits = array_values(SimplePie_Misc::array_unique($credits));
+ }
+ }
+ else
+ {
+ $credits = $credits_parent;
+ }
+
+ // DESCRIPTION
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
+ {
+ $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $description = $description_parent;
+ }
+
+ // HASHES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
+ {
+ $value = null;
+ $algo = null;
+ if (isset($hash['data']))
+ {
+ $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($hash['attribs']['']['algo']))
+ {
+ $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $algo = 'md5';
+ }
+ $hashes[] = $algo.':'.$value;
+ }
+ if (is_array($hashes))
+ {
+ $hashes = array_values(SimplePie_Misc::array_unique($hashes));
+ }
+ }
+ else
+ {
+ $hashes = $hashes_parent;
+ }
+
+ // KEYWORDS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
+ {
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords[] = trim($word);
+ }
+ unset($temp);
+ }
+ if (is_array($keywords))
+ {
+ $keywords = array_values(SimplePie_Misc::array_unique($keywords));
+ }
+ }
+ else
+ {
+ $keywords = $keywords_parent;
+ }
+
+ // PLAYER
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
+ {
+ $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ $player = $player_parent;
+ }
+
+ // RATINGS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
+ {
+ $rating_scheme = null;
+ $rating_value = null;
+ if (isset($rating['attribs']['']['scheme']))
+ {
+ $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $rating_scheme = 'urn:simple';
+ }
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ if (is_array($ratings))
+ {
+ $ratings = array_values(SimplePie_Misc::array_unique($ratings));
+ }
+ }
+ else
+ {
+ $ratings = $ratings_parent;
+ }
+
+ // RESTRICTIONS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
+ {
+ $restriction_relationship = null;
+ $restriction_type = null;
+ $restriction_value = null;
+ if (isset($restriction['attribs']['']['relationship']))
+ {
+ $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['attribs']['']['type']))
+ {
+ $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['data']))
+ {
+ $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ if (is_array($restrictions))
+ {
+ $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
+ }
+ }
+ else
+ {
+ $restrictions = $restrictions_parent;
+ }
+
+ // THUMBNAILS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
+ {
+ $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ if (is_array($thumbnails))
+ {
+ $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
+ }
+ }
+ else
+ {
+ $thumbnails = $thumbnails_parent;
+ }
+
+ // TITLES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
+ {
+ $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $title = $title_parent;
+ }
+
+ $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
+ }
+ }
+ }
+
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
+ {
+ if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
+ {
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+ if (isset($link['attribs']['']['type']))
+ {
+ $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($link['attribs']['']['length']))
+ {
+ $length = ceil($link['attribs']['']['length']);
+ }
+
+ // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
+ $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
+ }
+ }
+
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
+ {
+ if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
+ {
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+ if (isset($link['attribs']['']['type']))
+ {
+ $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($link['attribs']['']['length']))
+ {
+ $length = ceil($link['attribs']['']['length']);
+ }
+
+ // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
+ $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
+ }
+ }
+
+ if ($enclosure = $this->get_item_tags('', 'enclosure'))
+ {
+ if (isset($enclosure[0]['attribs']['']['url']))
+ {
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
+ if (isset($enclosure[0]['attribs']['']['type']))
+ {
+ $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($enclosure[0]['attribs']['']['length']))
+ {
+ $length = ceil($enclosure[0]['attribs']['']['length']);
+ }
+
+ // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
+ $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
+ }
+ }
+
+ if (sizeof($this->data['enclosures']) == 0)
+ {
+ // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
+ $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
+ }
+
+ $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
+ }
+ if (!empty($this->data['enclosures']))
+ {
+ return $this->data['enclosures'];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_latitude()
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
+ {
+ return (float) $match[1];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_longitude()
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
+ {
+ return (float) $match[2];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_source()
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
+ {
+ return new $this->feed->source_class($this, $return[0]);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Creates the add_to_* methods' return data
+ *
+ * @access private
+ * @param string $item_url String to prefix to the item permalink
+ * @param string $title_url String to prefix to the item title
+ * (and suffix to the item permalink)
+ * @return mixed URL if feed exists, false otherwise
+ */
+ function add_to_service($item_url, $title_url = null)
+ {
+ if ($this->get_permalink() !== null)
+ {
+ $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
+ if ($title_url !== null && $this->get_title() !== null)
+ {
+ $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
+ }
+ return $return;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function add_to_blinklist()
+ {
+ return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
+ }
+
+ function add_to_blogmarks()
+ {
+ return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
+ }
+
+ function add_to_delicious()
+ {
+ return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
+ }
+
+ function add_to_digg()
+ {
+ return $this->add_to_service('http://digg.com/submit?phase=2&URL=');
+ }
+
+ function add_to_furl()
+ {
+ return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
+ }
+
+ function add_to_magnolia()
+ {
+ return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
+ }
+
+ function add_to_myweb20()
+ {
+ return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
+ }
+
+ function add_to_newsvine()
+ {
+ return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
+ }
+
+ function add_to_reddit()
+ {
+ return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
+ }
+
+ function add_to_segnalo()
+ {
+ return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
+ }
+
+ function add_to_simpy()
+ {
+ return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
+ }
+
+ function add_to_spurl()
+ {
+ return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
+ }
+
+ function add_to_wists()
+ {
+ return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
+ }
+
+ function search_technorati()
+ {
+ return $this->add_to_service('http://www.technorati.com/search/');
+ }
+}
+
+class SimplePie_Source
+{
+ var $item;
+ var $data = array();
+
+ function SimplePie_Source($item, $data)
+ {
+ $this->item = $item;
+ $this->data = $data;
+ }
+
+ function __toString()
+ {
+ return md5(serialize($this->data));
+ }
+
+ /**
+ * Remove items that link back to this before destroying this object
+ */
+ function __destruct()
+ {
+ unset($this->item);
+ }
+
+ function get_source_tags($namespace, $tag)
+ {
+ if (isset($this->data['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][$namespace][$tag];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_base($element = array())
+ {
+ return $this->item->get_base($element);
+ }
+
+ function sanitize($data, $type, $base = '')
+ {
+ return $this->item->sanitize($data, $type, $base);
+ }
+
+ function get_item()
+ {
+ return $this->item;
+ }
+
+ function get_title()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags('', 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_categories()
+ {
+ $categories = array();
+
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['attribs']['']['term']))
+ {
+ $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
+ }
+ foreach ((array) $this->get_source_tags('', 'category') as $category)
+ {
+ $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
+ {
+ $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
+ {
+ $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($categories))
+ {
+ return SimplePie_Misc::array_unique($categories);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_author($key = 0)
+ {
+ $authors = $this->get_authors();
+ if (isset($authors[$key]))
+ {
+ return $authors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_authors()
+ {
+ $authors = array();
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
+ }
+ }
+ if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $authors[] =& new $this->item->feed->author_class($name, $url, $email);
+ }
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
+ {
+ $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
+ {
+ $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
+ {
+ $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($authors))
+ {
+ return SimplePie_Misc::array_unique($authors);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_contributor($key = 0)
+ {
+ $contributors = $this->get_contributors();
+ if (isset($contributors[$key]))
+ {
+ return $contributors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_contributors()
+ {
+ $contributors = array();
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
+ }
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
+ }
+ }
+
+ if (!empty($contributors))
+ {
+ return SimplePie_Misc::array_unique($contributors);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_link($key = 0, $rel = 'alternate')
+ {
+ $links = $this->get_links($rel);
+ if (isset($links[$key]))
+ {
+ return $links[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Added for parity between the parent-level and the item/entry-level.
+ */
+ function get_permalink()
+ {
+ return $this->get_link(0);
+ }
+
+ function get_links($rel = 'alternate')
+ {
+ if (!isset($this->data['links']))
+ {
+ $this->data['links'] = array();
+ if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
+ {
+ foreach ($links as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+ }
+ }
+ }
+ if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
+ {
+ foreach ($links as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+
+ }
+ }
+ }
+ if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_source_tags('', 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+
+ $keys = array_keys($this->data['links']);
+ foreach ($keys as $key)
+ {
+ if (SimplePie_Misc::is_isegment_nz_nc($key))
+ {
+ if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
+ $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
+ }
+ else
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
+ }
+ }
+ elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
+ {
+ $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
+ }
+ $this->data['links'][$key] = array_unique($this->data['links'][$key]);
+ }
+ }
+
+ if (isset($this->data['links'][$rel]))
+ {
+ return $this->data['links'][$rel];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_description()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags('', 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_copyright()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags('', 'copyright'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_language()
+ {
+ if ($return = $this->get_source_tags('', 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['xml_lang']))
+ {
+ return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_latitude()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
+ {
+ return (float) $match[1];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_longitude()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
+ {
+ return (float) $match[2];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_image_url()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
+ {
+ return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Author
+{
+ var $name;
+ var $link;
+ var $email;
+
+ // Constructor, used to input the data
+ function SimplePie_Author($name = null, $link = null, $email = null)
+ {
+ $this->name = $name;
+ $this->link = $link;
+ $this->email = $email;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_name()
+ {
+ if ($this->name !== null)
+ {
+ return $this->name;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_link()
+ {
+ if ($this->link !== null)
+ {
+ return $this->link;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_email()
+ {
+ if ($this->email !== null)
+ {
+ return $this->email;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Category
+{
+ var $term;
+ var $scheme;
+ var $label;
+
+ // Constructor, used to input the data
+ function SimplePie_Category($term = null, $scheme = null, $label = null)
+ {
+ $this->term = $term;
+ $this->scheme = $scheme;
+ $this->label = $label;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_term()
+ {
+ if ($this->term !== null)
+ {
+ return $this->term;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_scheme()
+ {
+ if ($this->scheme !== null)
+ {
+ return $this->scheme;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_label()
+ {
+ if ($this->label !== null)
+ {
+ return $this->label;
+ }
+ else
+ {
+ return $this->get_term();
+ }
+ }
+}
+
+class SimplePie_Enclosure
+{
+ var $bitrate;
+ var $captions;
+ var $categories;
+ var $channels;
+ var $copyright;
+ var $credits;
+ var $description;
+ var $duration;
+ var $expression;
+ var $framerate;
+ var $handler;
+ var $hashes;
+ var $height;
+ var $javascript;
+ var $keywords;
+ var $lang;
+ var $length;
+ var $link;
+ var $medium;
+ var $player;
+ var $ratings;
+ var $restrictions;
+ var $samplingrate;
+ var $thumbnails;
+ var $title;
+ var $type;
+ var $width;
+
+ // Constructor, used to input the data
+ function SimplePie_Enclosure($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
+ {
+ $this->bitrate = $bitrate;
+ $this->captions = $captions;
+ $this->categories = $categories;
+ $this->channels = $channels;
+ $this->copyright = $copyright;
+ $this->credits = $credits;
+ $this->description = $description;
+ $this->duration = $duration;
+ $this->expression = $expression;
+ $this->framerate = $framerate;
+ $this->hashes = $hashes;
+ $this->height = $height;
+ $this->javascript = $javascript;
+ $this->keywords = $keywords;
+ $this->lang = $lang;
+ $this->length = $length;
+ $this->link = $link;
+ $this->medium = $medium;
+ $this->player = $player;
+ $this->ratings = $ratings;
+ $this->restrictions = $restrictions;
+ $this->samplingrate = $samplingrate;
+ $this->thumbnails = $thumbnails;
+ $this->title = $title;
+ $this->type = $type;
+ $this->width = $width;
+ if (class_exists('idna_convert'))
+ {
+ $idn =& new idna_convert;
+ $parsed = SimplePie_Misc::parse_url($link);
+ $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
+ }
+ $this->handler = $this->get_handler(); // Needs to load last
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_bitrate()
+ {
+ if ($this->bitrate !== null)
+ {
+ return $this->bitrate;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_caption($key = 0)
+ {
+ $captions = $this->get_captions();
+ if (isset($captions[$key]))
+ {
+ return $captions[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_captions()
+ {
+ if ($this->captions !== null)
+ {
+ return $this->captions;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_categories()
+ {
+ if ($this->categories !== null)
+ {
+ return $this->categories;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_channels()
+ {
+ if ($this->channels !== null)
+ {
+ return $this->channels;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_copyright()
+ {
+ if ($this->copyright !== null)
+ {
+ return $this->copyright;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_credit($key = 0)
+ {
+ $credits = $this->get_credits();
+ if (isset($credits[$key]))
+ {
+ return $credits[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_credits()
+ {
+ if ($this->credits !== null)
+ {
+ return $this->credits;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_description()
+ {
+ if ($this->description !== null)
+ {
+ return $this->description;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_duration($convert = false)
+ {
+ if ($this->duration !== null)
+ {
+ if ($convert)
+ {
+ $time = SimplePie_Misc::time_hms($this->duration);
+ return $time;
+ }
+ else
+ {
+ return $this->duration;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_expression()
+ {
+ if ($this->expression !== null)
+ {
+ return $this->expression;
+ }
+ else
+ {
+ return 'full';
+ }
+ }
+
+ function get_extension()
+ {
+ if ($this->link !== null)
+ {
+ $url = SimplePie_Misc::parse_url($this->link);
+ if ($url['path'] !== '')
+ {
+ return pathinfo($url['path'], PATHINFO_EXTENSION);
+ }
+ }
+ return null;
+ }
+
+ function get_framerate()
+ {
+ if ($this->framerate !== null)
+ {
+ return $this->framerate;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_handler()
+ {
+ return $this->get_real_type(true);
+ }
+
+ function get_hash($key = 0)
+ {
+ $hashes = $this->get_hashes();
+ if (isset($hashes[$key]))
+ {
+ return $hashes[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_hashes()
+ {
+ if ($this->hashes !== null)
+ {
+ return $this->hashes;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_height()
+ {
+ if ($this->height !== null)
+ {
+ return $this->height;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_language()
+ {
+ if ($this->lang !== null)
+ {
+ return $this->lang;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_keyword($key = 0)
+ {
+ $keywords = $this->get_keywords();
+ if (isset($keywords[$key]))
+ {
+ return $keywords[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_keywords()
+ {
+ if ($this->keywords !== null)
+ {
+ return $this->keywords;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_length()
+ {
+ if ($this->length !== null)
+ {
+ return $this->length;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_link()
+ {
+ if ($this->link !== null)
+ {
+ return urldecode($this->link);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_medium()
+ {
+ if ($this->medium !== null)
+ {
+ return $this->medium;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_player()
+ {
+ if ($this->player !== null)
+ {
+ return $this->player;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_rating($key = 0)
+ {
+ $ratings = $this->get_ratings();
+ if (isset($ratings[$key]))
+ {
+ return $ratings[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_ratings()
+ {
+ if ($this->ratings !== null)
+ {
+ return $this->ratings;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_restriction($key = 0)
+ {
+ $restrictions = $this->get_restrictions();
+ if (isset($restrictions[$key]))
+ {
+ return $restrictions[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_restrictions()
+ {
+ if ($this->restrictions !== null)
+ {
+ return $this->restrictions;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_sampling_rate()
+ {
+ if ($this->samplingrate !== null)
+ {
+ return $this->samplingrate;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_size()
+ {
+ $length = $this->get_length();
+ if ($length !== null)
+ {
+ return round($length/1048576, 2);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_thumbnail($key = 0)
+ {
+ $thumbnails = $this->get_thumbnails();
+ if (isset($thumbnails[$key]))
+ {
+ return $thumbnails[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_thumbnails()
+ {
+ if ($this->thumbnails !== null)
+ {
+ return $this->thumbnails;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_title()
+ {
+ if ($this->title !== null)
+ {
+ return $this->title;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_width()
+ {
+ if ($this->width !== null)
+ {
+ return $this->width;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function native_embed($options='')
+ {
+ return $this->embed($options, true);
+ }
+
+ /**
+ * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
+ */
+ function embed($options = '', $native = false)
+ {
+ // Set up defaults
+ $audio = '';
+ $video = '';
+ $alt = '';
+ $altclass = '';
+ $loop = 'false';
+ $width = 'auto';
+ $height = 'auto';
+ $bgcolor = '#ffffff';
+ $mediaplayer = '';
+ $widescreen = false;
+ $handler = $this->get_handler();
+ $type = $this->get_real_type();
+
+ // Process options and reassign values as necessary
+ if (is_array($options))
+ {
+ extract($options);
+ }
+ else
+ {
+ $options = explode(',', $options);
+ foreach($options as $option)
+ {
+ $opt = explode(':', $option, 2);
+ if (isset($opt[0], $opt[1]))
+ {
+ $opt[0] = trim($opt[0]);
+ $opt[1] = trim($opt[1]);
+ switch ($opt[0])
+ {
+ case 'audio':
+ $audio = $opt[1];
+ break;
+
+ case 'video':
+ $video = $opt[1];
+ break;
+
+ case 'alt':
+ $alt = $opt[1];
+ break;
+
+ case 'altclass':
+ $altclass = $opt[1];
+ break;
+
+ case 'loop':
+ $loop = $opt[1];
+ break;
+
+ case 'width':
+ $width = $opt[1];
+ break;
+
+ case 'height':
+ $height = $opt[1];
+ break;
+
+ case 'bgcolor':
+ $bgcolor = $opt[1];
+ break;
+
+ case 'mediaplayer':
+ $mediaplayer = $opt[1];
+ break;
+
+ case 'widescreen':
+ $widescreen = $opt[1];
+ break;
+ }
+ }
+ }
+ }
+
+ $mime = explode('/', $type, 2);
+ $mime = $mime[0];
+
+ // Process values for 'auto'
+ if ($width == 'auto')
+ {
+ if ($mime == 'video')
+ {
+ if ($height == 'auto')
+ {
+ $width = 480;
+ }
+ elseif ($widescreen)
+ {
+ $width = round((intval($height)/9)*16);
+ }
+ else
+ {
+ $width = round((intval($height)/3)*4);
+ }
+ }
+ else
+ {
+ $width = '100%';
+ }
+ }
+
+ if ($height == 'auto')
+ {
+ if ($mime == 'audio')
+ {
+ $height = 0;
+ }
+ elseif ($mime == 'video')
+ {
+ if ($width == 'auto')
+ {
+ if ($widescreen)
+ {
+ $height = 270;
+ }
+ else
+ {
+ $height = 360;
+ }
+ }
+ elseif ($widescreen)
+ {
+ $height = round((intval($width)/16)*9);
+ }
+ else
+ {
+ $height = round((intval($width)/4)*3);
+ }
+ }
+ else
+ {
+ $height = 376;
+ }
+ }
+ elseif ($mime == 'audio')
+ {
+ $height = 0;
+ }
+
+ // Set proper placeholder value
+ if ($mime == 'audio')
+ {
+ $placeholder = $audio;
+ }
+ elseif ($mime == 'video')
+ {
+ $placeholder = $video;
+ }
+
+ $embed = '';
+
+ // Make sure the JS library is included
+ if (!$native)
+ {
+ static $javascript_outputted = null;
+ if (!$javascript_outputted && $this->javascript)
+ {
+ $embed .= '';
+ $javascript_outputted = true;
+ }
+ }
+
+ // Odeo Feed MP3's
+ if ($handler == 'odeo')
+ {
+ if ($native)
+ {
+ $embed .= '';
+ }
+ else
+ {
+ $embed .= '';
+ }
+ }
+
+ // Flash
+ elseif ($handler == 'flash')
+ {
+ if ($native)
+ {
+ $embed .= "";
+ }
+ else
+ {
+ $embed .= "";
+ }
+ }
+
+ // Flash Media Player file types.
+ // Preferred handler for MP3 file types.
+ elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
+ {
+ $height += 20;
+ if ($native)
+ {
+ $embed .= "";
+ }
+ else
+ {
+ $embed .= "";
+ }
+ }
+
+ // QuickTime 7 file types. Need to test with QuickTime 6.
+ // Only handle MP3's if the Flash Media Player is not present.
+ elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
+ {
+ $height += 16;
+ if ($native)
+ {
+ if ($placeholder != ""){
+ $embed .= "";
+ }
+ else {
+ $embed .= "";
+ }
+ }
+ else
+ {
+ $embed .= "";
+ }
+ }
+
+ // Windows Media
+ elseif ($handler == 'wmedia')
+ {
+ $height += 45;
+ if ($native)
+ {
+ $embed .= "";
+ }
+ else
+ {
+ $embed .= "";
+ }
+ }
+
+ // Everything else
+ else $embed .= '' . $alt . '';
+
+ return $embed;
+ }
+
+ function get_real_type($find_handler = false)
+ {
+ // If it's Odeo, let's get it out of the way.
+ if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
+ {
+ return 'odeo';
+ }
+
+ // Mime-types by handler.
+ $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
+ $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
+ $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime
+ $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media
+ $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
+
+ if ($this->get_type() !== null)
+ {
+ $type = strtolower($this->type);
+ }
+ else
+ {
+ $type = null;
+ }
+
+ // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
+ if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
+ {
+ switch (strtolower($this->get_extension()))
+ {
+ // Audio mime-types
+ case 'aac':
+ case 'adts':
+ $type = 'audio/acc';
+ break;
+
+ case 'aif':
+ case 'aifc':
+ case 'aiff':
+ case 'cdda':
+ $type = 'audio/aiff';
+ break;
+
+ case 'bwf':
+ $type = 'audio/wav';
+ break;
+
+ case 'kar':
+ case 'mid':
+ case 'midi':
+ case 'smf':
+ $type = 'audio/midi';
+ break;
+
+ case 'm4a':
+ $type = 'audio/x-m4a';
+ break;
+
+ case 'mp3':
+ case 'swa':
+ $type = 'audio/mp3';
+ break;
+
+ case 'wav':
+ $type = 'audio/wav';
+ break;
+
+ case 'wax':
+ $type = 'audio/x-ms-wax';
+ break;
+
+ case 'wma':
+ $type = 'audio/x-ms-wma';
+ break;
+
+ // Video mime-types
+ case '3gp':
+ case '3gpp':
+ $type = 'video/3gpp';
+ break;
+
+ case '3g2':
+ case '3gp2':
+ $type = 'video/3gpp2';
+ break;
+
+ case 'asf':
+ $type = 'video/x-ms-asf';
+ break;
+
+ case 'flv':
+ $type = 'video/x-flv';
+ break;
+
+ case 'm1a':
+ case 'm1s':
+ case 'm1v':
+ case 'm15':
+ case 'm75':
+ case 'mp2':
+ case 'mpa':
+ case 'mpeg':
+ case 'mpg':
+ case 'mpm':
+ case 'mpv':
+ $type = 'video/mpeg';
+ break;
+
+ case 'm4v':
+ $type = 'video/x-m4v';
+ break;
+
+ case 'mov':
+ case 'qt':
+ $type = 'video/quicktime';
+ break;
+
+ case 'mp4':
+ case 'mpg4':
+ $type = 'video/mp4';
+ break;
+
+ case 'sdv':
+ $type = 'video/sd-video';
+ break;
+
+ case 'wm':
+ $type = 'video/x-ms-wm';
+ break;
+
+ case 'wmv':
+ $type = 'video/x-ms-wmv';
+ break;
+
+ case 'wvx':
+ $type = 'video/x-ms-wvx';
+ break;
+
+ // Flash mime-types
+ case 'spl':
+ $type = 'application/futuresplash';
+ break;
+
+ case 'swf':
+ $type = 'application/x-shockwave-flash';
+ break;
+ }
+ }
+
+ if ($find_handler)
+ {
+ if (in_array($type, $types_flash))
+ {
+ return 'flash';
+ }
+ elseif (in_array($type, $types_fmedia))
+ {
+ return 'fmedia';
+ }
+ elseif (in_array($type, $types_quicktime))
+ {
+ return 'quicktime';
+ }
+ elseif (in_array($type, $types_wmedia))
+ {
+ return 'wmedia';
+ }
+ elseif (in_array($type, $types_mp3))
+ {
+ return 'mp3';
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else
+ {
+ return $type;
+ }
+ }
+}
+
+class SimplePie_Caption
+{
+ var $type;
+ var $lang;
+ var $startTime;
+ var $endTime;
+ var $text;
+
+ // Constructor, used to input the data
+ function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
+ {
+ $this->type = $type;
+ $this->lang = $lang;
+ $this->startTime = $startTime;
+ $this->endTime = $endTime;
+ $this->text = $text;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_endtime()
+ {
+ if ($this->endTime !== null)
+ {
+ return $this->endTime;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_language()
+ {
+ if ($this->lang !== null)
+ {
+ return $this->lang;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_starttime()
+ {
+ if ($this->startTime !== null)
+ {
+ return $this->startTime;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_text()
+ {
+ if ($this->text !== null)
+ {
+ return $this->text;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Credit
+{
+ var $role;
+ var $scheme;
+ var $name;
+
+ // Constructor, used to input the data
+ function SimplePie_Credit($role = null, $scheme = null, $name = null)
+ {
+ $this->role = $role;
+ $this->scheme = $scheme;
+ $this->name = $name;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_role()
+ {
+ if ($this->role !== null)
+ {
+ return $this->role;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_scheme()
+ {
+ if ($this->scheme !== null)
+ {
+ return $this->scheme;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_name()
+ {
+ if ($this->name !== null)
+ {
+ return $this->name;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Copyright
+{
+ var $url;
+ var $label;
+
+ // Constructor, used to input the data
+ function SimplePie_Copyright($url = null, $label = null)
+ {
+ $this->url = $url;
+ $this->label = $label;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_url()
+ {
+ if ($this->url !== null)
+ {
+ return $this->url;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_attribution()
+ {
+ if ($this->label !== null)
+ {
+ return $this->label;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Rating
+{
+ var $scheme;
+ var $value;
+
+ // Constructor, used to input the data
+ function SimplePie_Rating($scheme = null, $value = null)
+ {
+ $this->scheme = $scheme;
+ $this->value = $value;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_scheme()
+ {
+ if ($this->scheme !== null)
+ {
+ return $this->scheme;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_value()
+ {
+ if ($this->value !== null)
+ {
+ return $this->value;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Restriction
+{
+ var $relationship;
+ var $type;
+ var $value;
+
+ // Constructor, used to input the data
+ function SimplePie_Restriction($relationship = null, $type = null, $value = null)
+ {
+ $this->relationship = $relationship;
+ $this->type = $type;
+ $this->value = $value;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_relationship()
+ {
+ if ($this->relationship !== null)
+ {
+ return $this->relationship;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_value()
+ {
+ if ($this->value !== null)
+ {
+ return $this->value;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+/**
+ * @todo Move to properly supporting RFC2616 (HTTP/1.1)
+ */
+class SimplePie_File
+{
+ var $url;
+ var $useragent;
+ var $success = true;
+ var $headers = array();
+ var $body;
+ var $status_code;
+ var $redirects = 0;
+ var $error;
+ var $method = SIMPLEPIE_FILE_SOURCE_NONE;
+
+ function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
+ {
+ if (class_exists('idna_convert'))
+ {
+ $idn =& new idna_convert;
+ $parsed = SimplePie_Misc::parse_url($url);
+ $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
+ }
+ $this->url = $url;
+ $this->useragent = $useragent;
+ if (preg_match('/^http(s)?:\/\//i', $url))
+ {
+ if ($useragent === null)
+ {
+ $useragent = ini_get('user_agent');
+ $this->useragent = $useragent;
+ }
+ if (!is_array($headers))
+ {
+ $headers = array();
+ }
+ if (!$force_fsockopen && function_exists('curl_exec'))
+ {
+ $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
+ $fp = curl_init();
+ $headers2 = array();
+ foreach ($headers as $key => $value)
+ {
+ $headers2[] = "$key: $value";
+ }
+ if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
+ {
+ curl_setopt($fp, CURLOPT_ENCODING, '');
+ }
+ curl_setopt($fp, CURLOPT_URL, $url);
+ curl_setopt($fp, CURLOPT_HEADER, 1);
+ curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
+ curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
+ curl_setopt($fp, CURLOPT_REFERER, $url);
+ curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
+ curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
+ if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
+ {
+ curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
+ curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
+ }
+
+ $this->headers = curl_exec($fp);
+ if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
+ {
+ curl_setopt($fp, CURLOPT_ENCODING, 'none');
+ $this->headers = curl_exec($fp);
+ }
+ if (curl_errno($fp))
+ {
+ $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
+ $this->success = false;
+ }
+ else
+ {
+ $info = curl_getinfo($fp);
+ curl_close($fp);
+ $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
+ $this->headers = array_pop($this->headers);
+ $parser =& new SimplePie_HTTP_Parser($this->headers);
+ if ($parser->parse())
+ {
+ $this->headers = $parser->headers;
+ $this->body = $parser->body;
+ $this->status_code = $parser->status_code;
+ if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
+ {
+ $this->redirects++;
+ $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
+ return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
+ }
+ }
+ }
+ }
+ else
+ {
+ $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
+ $url_parts = parse_url($url);
+ if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
+ {
+ $url_parts['host'] = "ssl://$url_parts[host]";
+ $url_parts['port'] = 443;
+ }
+ if (!isset($url_parts['port']))
+ {
+ $url_parts['port'] = 80;
+ }
+ $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
+ if (!$fp)
+ {
+ $this->error = 'fsockopen error: ' . $errstr;
+ $this->success = false;
+ }
+ else
+ {
+ stream_set_timeout($fp, $timeout);
+ if (isset($url_parts['path']))
+ {
+ if (isset($url_parts['query']))
+ {
+ $get = "$url_parts[path]?$url_parts[query]";
+ }
+ else
+ {
+ $get = $url_parts['path'];
+ }
+ }
+ else
+ {
+ $get = '/';
+ }
+ $out = "GET $get HTTP/1.0\r\n";
+ $out .= "Host: $url_parts[host]\r\n";
+ $out .= "User-Agent: $useragent\r\n";
+ if (function_exists('gzinflate'))
+ {
+ $out .= "Accept-Encoding: gzip,deflate\r\n";
+ }
+
+ if (isset($url_parts['user']) && isset($url_parts['pass']))
+ {
+ $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
+ }
+ foreach ($headers as $key => $value)
+ {
+ $out .= "$key: $value\r\n";
+ }
+ $out .= "Connection: Close\r\n\r\n";
+ fwrite($fp, $out);
+
+ $info = stream_get_meta_data($fp);
+
+ $this->headers = '';
+ while (!$info['eof'] && !$info['timed_out'])
+ {
+ $this->headers .= fread($fp, 1160);
+ $info = stream_get_meta_data($fp);
+ }
+ if (!$info['timed_out'])
+ {
+ $parser =& new SimplePie_HTTP_Parser($this->headers);
+ if ($parser->parse())
+ {
+ $this->headers = $parser->headers;
+ $this->body = $parser->body;
+ $this->status_code = $parser->status_code;
+ if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
+ {
+ $this->redirects++;
+ $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
+ return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
+ }
+ if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
+ {
+ if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
+ {
+ $this->body = substr($this->body, 10);
+ }
+ $this->body = gzinflate($this->body);
+ }
+ }
+ }
+ else
+ {
+ $this->error = 'fsocket timed out';
+ $this->success = false;
+ }
+ fclose($fp);
+ }
+ }
+ }
+ else
+ {
+ $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
+ if (!$this->body = file_get_contents($url))
+ {
+ $this->error = 'file_get_contents could not read the file';
+ $this->success = false;
+ }
+ }
+ }
+}
+
+/**
+ * HTTP Response Parser
+ *
+ * @package SimplePie
+ */
+class SimplePie_HTTP_Parser
+{
+ /**
+ * HTTP Version
+ *
+ * @access public
+ * @var float
+ */
+ var $http_version = 0.0;
+
+ /**
+ * Status code
+ *
+ * @access public
+ * @var int
+ */
+ var $status_code = 0;
+
+ /**
+ * Reason phrase
+ *
+ * @access public
+ * @var string
+ */
+ var $reason = '';
+
+ /**
+ * Key/value pairs of the headers
+ *
+ * @access public
+ * @var array
+ */
+ var $headers = array();
+
+ /**
+ * Body of the response
+ *
+ * @access public
+ * @var string
+ */
+ var $body = '';
+
+ /**
+ * Current state of the state machine
+ *
+ * @access private
+ * @var string
+ */
+ var $state = 'http_version';
+
+ /**
+ * Input data
+ *
+ * @access private
+ * @var string
+ */
+ var $data = '';
+
+ /**
+ * Input data length (to avoid calling strlen() everytime this is needed)
+ *
+ * @access private
+ * @var int
+ */
+ var $data_length = 0;
+
+ /**
+ * Current position of the pointer
+ *
+ * @var int
+ * @access private
+ */
+ var $position = 0;
+
+ /**
+ * Name of the hedaer currently being parsed
+ *
+ * @access private
+ * @var string
+ */
+ var $name = '';
+
+ /**
+ * Value of the hedaer currently being parsed
+ *
+ * @access private
+ * @var string
+ */
+ var $value = '';
+
+ /**
+ * Create an instance of the class with the input data
+ *
+ * @access public
+ * @param string $data Input data
+ */
+ function SimplePie_HTTP_Parser($data)
+ {
+ $this->data = $data;
+ $this->data_length = strlen($this->data);
+ }
+
+ /**
+ * Parse the input data
+ *
+ * @access public
+ * @return bool true on success, false on failure
+ */
+ function parse()
+ {
+ while ($this->state && $this->state !== 'emit' && $this->has_data())
+ {
+ $state = $this->state;
+ $this->$state();
+ }
+ $this->data = '';
+ if ($this->state === 'emit')
+ {
+ return true;
+ }
+ else
+ {
+ $this->http_version = '';
+ $this->status_code = '';
+ $this->reason = '';
+ $this->headers = array();
+ $this->body = '';
+ return false;
+ }
+ }
+
+ /**
+ * Check whether there is data beyond the pointer
+ *
+ * @access private
+ * @return bool true if there is further data, false if not
+ */
+ function has_data()
+ {
+ return (bool) ($this->position < $this->data_length);
+ }
+
+ /**
+ * See if the next character is LWS
+ *
+ * @access private
+ * @return bool true if the next character is LWS, false if not
+ */
+ function is_linear_whitespace()
+ {
+ return (bool) ($this->data[$this->position] === "\x09"
+ || $this->data[$this->position] === "\x20"
+ || ($this->data[$this->position] === "\x0A"
+ && isset($this->data[$this->position + 1])
+ && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
+ }
+
+ /**
+ * Parse the HTTP version
+ *
+ * @access private
+ */
+ function http_version()
+ {
+ if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
+ {
+ $len = strspn($this->data, '0123456789.', 5);
+ $this->http_version = substr($this->data, 5, $len);
+ $this->position += 5 + $len;
+ if (substr_count($this->http_version, '.') <= 1)
+ {
+ $this->http_version = (float) $this->http_version;
+ $this->position += strspn($this->data, "\x09\x20", $this->position);
+ $this->state = 'status';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ /**
+ * Parse the status code
+ *
+ * @access private
+ */
+ function status()
+ {
+ if ($len = strspn($this->data, '0123456789', $this->position))
+ {
+ $this->status_code = (int) substr($this->data, $this->position, $len);
+ $this->position += $len;
+ $this->state = 'reason';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ /**
+ * Parse the reason phrase
+ *
+ * @access private
+ */
+ function reason()
+ {
+ $len = strcspn($this->data, "\x0A", $this->position);
+ $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
+ $this->position += $len + 1;
+ $this->state = 'new_line';
+ }
+
+ /**
+ * Deal with a new line, shifting data around as needed
+ *
+ * @access private
+ */
+ function new_line()
+ {
+ $this->value = trim($this->value, "\x0D\x20");
+ if ($this->name !== '' && $this->value !== '')
+ {
+ $this->name = strtolower($this->name);
+ if (isset($this->headers[$this->name]))
+ {
+ $this->headers[$this->name] .= ', ' . $this->value;
+ }
+ else
+ {
+ $this->headers[$this->name] = $this->value;
+ }
+ }
+ $this->name = '';
+ $this->value = '';
+ if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
+ {
+ $this->position += 2;
+ $this->state = 'body';
+ }
+ elseif ($this->data[$this->position] === "\x0A")
+ {
+ $this->position++;
+ $this->state = 'body';
+ }
+ else
+ {
+ $this->state = 'name';
+ }
+ }
+
+ /**
+ * Parse a header name
+ *
+ * @access private
+ */
+ function name()
+ {
+ $len = strcspn($this->data, "\x0A:", $this->position);
+ if (isset($this->data[$this->position + $len]))
+ {
+ if ($this->data[$this->position + $len] === "\x0A")
+ {
+ $this->position += $len;
+ $this->state = 'new_line';
+ }
+ else
+ {
+ $this->name = substr($this->data, $this->position, $len);
+ $this->position += $len + 1;
+ $this->state = 'value';
+ }
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ /**
+ * Parse LWS, replacing consecutive LWS characters with a single space
+ *
+ * @access private
+ */
+ function linear_whitespace()
+ {
+ do
+ {
+ if (substr($this->data, $this->position, 2) === "\x0D\x0A")
+ {
+ $this->position += 2;
+ }
+ elseif ($this->data[$this->position] === "\x0A")
+ {
+ $this->position++;
+ }
+ $this->position += strspn($this->data, "\x09\x20", $this->position);
+ } while ($this->has_data() && $this->is_linear_whitespace());
+ $this->value .= "\x20";
+ }
+
+ /**
+ * See what state to move to while within non-quoted header values
+ *
+ * @access private
+ */
+ function value()
+ {
+ if ($this->is_linear_whitespace())
+ {
+ $this->linear_whitespace();
+ }
+ else
+ {
+ switch ($this->data[$this->position])
+ {
+ case '"':
+ $this->position++;
+ $this->state = 'quote';
+ break;
+
+ case "\x0A":
+ $this->position++;
+ $this->state = 'new_line';
+ break;
+
+ default:
+ $this->state = 'value_char';
+ break;
+ }
+ }
+ }
+
+ /**
+ * Parse a header value while outside quotes
+ *
+ * @access private
+ */
+ function value_char()
+ {
+ $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
+ $this->value .= substr($this->data, $this->position, $len);
+ $this->position += $len;
+ $this->state = 'value';
+ }
+
+ /**
+ * See what state to move to while within quoted header values
+ *
+ * @access private
+ */
+ function quote()
+ {
+ if ($this->is_linear_whitespace())
+ {
+ $this->linear_whitespace();
+ }
+ else
+ {
+ switch ($this->data[$this->position])
+ {
+ case '"':
+ $this->position++;
+ $this->state = 'value';
+ break;
+
+ case "\x0A":
+ $this->position++;
+ $this->state = 'new_line';
+ break;
+
+ case '\\':
+ $this->position++;
+ $this->state = 'quote_escaped';
+ break;
+
+ default:
+ $this->state = 'quote_char';
+ break;
+ }
+ }
+ }
+
+ /**
+ * Parse a header value while within quotes
+ *
+ * @access private
+ */
+ function quote_char()
+ {
+ $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
+ $this->value .= substr($this->data, $this->position, $len);
+ $this->position += $len;
+ $this->state = 'value';
+ }
+
+ /**
+ * Parse an escaped character within quotes
+ *
+ * @access private
+ */
+ function quote_escaped()
+ {
+ $this->value .= $this->data[$this->position];
+ $this->position++;
+ $this->state = 'quote';
+ }
+
+ /**
+ * Parse the body
+ *
+ * @access private
+ */
+ function body()
+ {
+ $this->body = substr($this->data, $this->position);
+ $this->state = 'emit';
+ }
+}
+
+class SimplePie_Cache
+{
+ /**
+ * Don't call the constructor. Please.
+ *
+ * @access private
+ */
+ function SimplePie_Cache()
+ {
+ trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
+ }
+
+ /**
+ * Create a new SimplePie_Cache object
+ *
+ * @static
+ * @access public
+ */
+ function create($location, $filename, $extension)
+ {
+ return new SimplePie_Cache_File($location, $filename, $extension);
+ }
+}
+
+class SimplePie_Cache_File
+{
+ var $location;
+ var $filename;
+ var $extension;
+ var $name;
+
+ function SimplePie_Cache_File($location, $filename, $extension)
+ {
+ $this->location = $location;
+ $this->filename = rawurlencode($filename);
+ $this->extension = rawurlencode($extension);
+ $this->name = "$location/$this->filename.$this->extension";
+ }
+
+ function save($data)
+ {
+ if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
+ {
+ if (is_a($data, 'SimplePie'))
+ {
+ $data = $data->data;
+ }
+
+ $data = serialize($data);
+
+ if (function_exists('file_put_contents'))
+ {
+ return (bool) file_put_contents($this->name, $data);
+ }
+ else
+ {
+ $fp = fopen($this->name, 'wb');
+ if ($fp)
+ {
+ fwrite($fp, $data);
+ fclose($fp);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ function load()
+ {
+ if (file_exists($this->name) && is_readable($this->name))
+ {
+ return unserialize(file_get_contents($this->name));
+ }
+ return false;
+ }
+
+ function mtime()
+ {
+ if (file_exists($this->name))
+ {
+ return filemtime($this->name);
+ }
+ return false;
+ }
+
+ function touch()
+ {
+ if (file_exists($this->name))
+ {
+ return touch($this->name);
+ }
+ return false;
+ }
+
+ function unlink()
+ {
+ if (file_exists($this->name))
+ {
+ return unlink($this->name);
+ }
+ return false;
+ }
+}
+
+class SimplePie_Misc
+{
+ function time_hms($seconds)
+ {
+ $time = '';
+
+ $hours = floor($seconds / 3600);
+ $remainder = $seconds % 3600;
+ if ($hours > 0)
+ {
+ $time .= $hours.':';
+ }
+
+ $minutes = floor($remainder / 60);
+ $seconds = $remainder % 60;
+ if ($minutes < 10 && $hours > 0)
+ {
+ $minutes = '0' . $minutes;
+ }
+ if ($seconds < 10)
+ {
+ $seconds = '0' . $seconds;
+ }
+
+ $time .= $minutes.':';
+ $time .= $seconds;
+
+ return $time;
+ }
+
+ function absolutize_url($relative, $base)
+ {
+ if ($relative !== '')
+ {
+ $relative = SimplePie_Misc::parse_url($relative);
+ if ($relative['scheme'] !== '')
+ {
+ $target = $relative;
+ }
+ elseif ($base !== '')
+ {
+ $base = SimplePie_Misc::parse_url($base);
+ $target = SimplePie_Misc::parse_url('');
+ if ($relative['authority'] !== '')
+ {
+ $target = $relative;
+ $target['scheme'] = $base['scheme'];
+ }
+ else
+ {
+ $target['scheme'] = $base['scheme'];
+ $target['authority'] = $base['authority'];
+ if ($relative['path'] !== '')
+ {
+ if (strpos($relative['path'], '/') === 0)
+ {
+ $target['path'] = $relative['path'];
+ }
+ elseif ($base['authority'] !== '' && $base['path'] === '')
+ {
+ $target['path'] = '/' . $relative['path'];
+ }
+ elseif (($last_segment = strrpos($base['path'], '/')) !== false)
+ {
+ $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
+ }
+ else
+ {
+ $target['path'] = $relative['path'];
+ }
+ $target['query'] = $relative['query'];
+ }
+ else
+ {
+ $target['path'] = $base['path'];
+ if ($relative['query'] !== '')
+ {
+ $target['query'] = $relative['query'];
+ }
+ elseif ($base['query'] !== '')
+ {
+ $target['query'] = $base['query'];
+ }
+ }
+ }
+ $target['fragment'] = $relative['fragment'];
+ }
+ else
+ {
+ // No base URL, just return the relative URL
+ $target = $relative;
+ }
+ $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
+ }
+ else
+ {
+ $return = $base;
+ }
+ $return = SimplePie_Misc::normalize_url($return);
+ return $return;
+ }
+
+ function remove_dot_segments($input)
+ {
+ $output = '';
+ while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
+ {
+ // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
+ if (strpos($input, '../') === 0)
+ {
+ $input = substr($input, 3);
+ }
+ elseif (strpos($input, './') === 0)
+ {
+ $input = substr($input, 2);
+ }
+ // 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,
+ elseif (strpos($input, '/./') === 0)
+ {
+ $input = substr_replace($input, '/', 0, 3);
+ }
+ elseif ($input == '/.')
+ {
+ $input = '/';
+ }
+ // 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,
+ elseif (strpos($input, '/../') === 0)
+ {
+ $input = substr_replace($input, '/', 0, 4);
+ $output = substr_replace($output, '', strrpos($output, '/'));
+ }
+ elseif ($input == '/..')
+ {
+ $input = '/';
+ $output = substr_replace($output, '', strrpos($output, '/'));
+ }
+ // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
+ elseif ($input == '.' || $input == '..')
+ {
+ $input = '';
+ }
+ // 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
+ elseif (($pos = strpos($input, '/', 1)) !== false)
+ {
+ $output .= substr($input, 0, $pos);
+ $input = substr_replace($input, '', 0, $pos);
+ }
+ else
+ {
+ $output .= $input;
+ $input = '';
+ }
+ }
+ return $output . $input;
+ }
+
+ function get_element($realname, $string)
+ {
+ $return = array();
+ $name = preg_quote($realname, '/');
+ if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
+ {
+ for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
+ {
+ $return[$i]['tag'] = $realname;
+ $return[$i]['full'] = $matches[$i][0][0];
+ $return[$i]['offset'] = $matches[$i][0][1];
+ if (strlen($matches[$i][3][0]) <= 2)
+ {
+ $return[$i]['self_closing'] = true;
+ }
+ else
+ {
+ $return[$i]['self_closing'] = false;
+ $return[$i]['content'] = $matches[$i][4][0];
+ }
+ $return[$i]['attribs'] = array();
+ if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
+ {
+ for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
+ {
+ if (count($attribs[$j]) == 2)
+ {
+ $attribs[$j][2] = $attribs[$j][1];
+ }
+ $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
+ }
+ }
+ }
+ }
+ return $return;
+ }
+
+ function element_implode($element)
+ {
+ $full = "<$element[tag]";
+ foreach ($element['attribs'] as $key => $value)
+ {
+ $key = strtolower($key);
+ $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
+ }
+ if ($element['self_closing'])
+ {
+ $full .= ' />';
+ }
+ else
+ {
+ $full .= ">$element[content]$element[tag]>";
+ }
+ return $full;
+ }
+
+ function error($message, $level, $file, $line)
+ {
+ switch ($level)
+ {
+ case E_USER_ERROR:
+ $note = 'PHP Error';
+ break;
+ case E_USER_WARNING:
+ $note = 'PHP Warning';
+ break;
+ case E_USER_NOTICE:
+ $note = 'PHP Notice';
+ break;
+ default:
+ $note = 'Unknown Error';
+ break;
+ }
+ error_log("$note: $message in $file on line $line", 0);
+ return $message;
+ }
+
+ /**
+ * If a file has been cached, retrieve and display it.
+ *
+ * This is most useful for caching images (get_favicon(), etc.),
+ * however it works for all cached files. This WILL NOT display ANY
+ * file/image/page/whatever, but rather only display what has already
+ * been cached by SimplePie.
+ *
+ * @access public
+ * @see SimplePie::get_favicon()
+ * @param str $identifier_url URL that is used to identify the content.
+ * This may or may not be the actual URL of the live content.
+ * @param str $cache_location Location of SimplePie's cache. Defaults
+ * to './cache'.
+ * @param str $cache_extension The file extension that the file was
+ * cached with. Defaults to 'spc'.
+ * @param str $cache_class Name of the cache-handling class being used
+ * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
+ * as-is unless you've overloaded the class.
+ * @param str $cache_name_function Obsolete. Exists for backwards
+ * compatibility reasons only.
+ */
+ function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
+ {
+ $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
+
+ if ($file = $cache->load())
+ {
+ if (isset($file['headers']['content-type']))
+ {
+ header('Content-type:' . $file['headers']['content-type']);
+ }
+ else
+ {
+ header('Content-type: application/octet-stream');
+ }
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
+ echo $file['body'];
+ exit;
+ }
+
+ die('Cached file for ' . $identifier_url . ' cannot be found.');
+ }
+
+ function fix_protocol($url, $http = 1)
+ {
+ $url = SimplePie_Misc::normalize_url($url);
+ $parsed = SimplePie_Misc::parse_url($url);
+ if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
+ {
+ return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
+ }
+
+ if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
+ {
+ return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
+ }
+
+ if ($http == 2 && $parsed['scheme'] !== '')
+ {
+ return "feed:$url";
+ }
+ elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
+ {
+ return substr_replace($url, 'podcast', 0, 4);
+ }
+ elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
+ {
+ return substr_replace($url, 'itpc', 0, 4);
+ }
+ else
+ {
+ return $url;
+ }
+ }
+
+ function parse_url($url)
+ {
+ static $cache = array();
+ if (isset($cache[$url]))
+ {
+ return $cache[$url];
+ }
+ elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
+ {
+ for ($i = count($match); $i <= 9; $i++)
+ {
+ $match[$i] = '';
+ }
+ return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
+ }
+ else
+ {
+ return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
+ }
+ }
+
+ function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
+ {
+ $return = '';
+ if ($scheme !== '')
+ {
+ $return .= "$scheme:";
+ }
+ if ($authority !== '')
+ {
+ $return .= "//$authority";
+ }
+ if ($path !== '')
+ {
+ $return .= $path;
+ }
+ if ($query !== '')
+ {
+ $return .= "?$query";
+ }
+ if ($fragment !== '')
+ {
+ $return .= "#$fragment";
+ }
+ return $return;
+ }
+
+ function normalize_url($url)
+ {
+ $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
+ $url = SimplePie_Misc::parse_url($url);
+ $url['scheme'] = strtolower($url['scheme']);
+ if ($url['authority'] !== '')
+ {
+ $url['authority'] = strtolower($url['authority']);
+ $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
+ }
+ return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
+ }
+
+ function percent_encoding_normalization($match)
+ {
+ $integer = hexdec($match[1]);
+ if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
+ {
+ return chr($integer);
+ }
+ else
+ {
+ return strtoupper($match[0]);
+ }
+ }
+
+ /**
+ * Remove bad UTF-8 bytes
+ *
+ * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
+ * FAQ: Multilingual Forms (modified to include full ASCII range)
+ *
+ * @author Geoffrey Sneddon
+ * @see http://www.w3.org/International/questions/qa-forms-utf-8
+ * @param string $str String to remove bad UTF-8 bytes from
+ * @return string UTF-8 string
+ */
+ function utf8_bad_replace($str)
+ {
+ if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
+ {
+ return $return;
+ }
+ elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
+ {
+ return $return;
+ }
+ elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches))
+ {
+ return implode("\xEF\xBF\xBD", $matches[0]);
+ }
+ elseif ($str !== '')
+ {
+ return "\xEF\xBF\xBD";
+ }
+ else
+ {
+ return '';
+ }
+ }
+
+ /**
+ * Converts a Windows-1252 encoded string to a UTF-8 encoded string
+ *
+ * @static
+ * @access public
+ * @param string $string Windows-1252 encoded string
+ * @return string UTF-8 encoded string
+ */
+ function windows_1252_to_utf8($string)
+ {
+ static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
+
+ return strtr($string, $convert_table);
+ }
+
+ function change_encoding($data, $input, $output)
+ {
+ $input = SimplePie_Misc::encoding($input);
+ $output = SimplePie_Misc::encoding($output);
+
+ // We fail to fail on non US-ASCII bytes
+ if ($input === 'US-ASCII')
+ {
+ static $non_ascii_octects = '';
+ if (!$non_ascii_octects)
+ {
+ for ($i = 0x80; $i <= 0xFF; $i++)
+ {
+ $non_ascii_octects .= chr($i);
+ }
+ }
+ $data = substr($data, 0, strcspn($data, $non_ascii_octects));
+ }
+
+ if (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
+ {
+ return $return;
+ }
+ elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
+ {
+ return $return;
+ }
+ elseif ($input == 'windows-1252' && $output == 'UTF-8')
+ {
+ return SimplePie_Misc::windows_1252_to_utf8($data);
+ }
+ elseif ($input == 'UTF-8' && $output == 'windows-1252')
+ {
+ return utf8_decode($data);
+ }
+ return $data;
+ }
+
+ function encoding($encoding)
+ {
+ // Character sets are case-insensitive (though we'll return them in the form given in their registration)
+ switch (strtoupper($encoding))
+ {
+ case 'ANSI_X3.110-1983':
+ case 'CSA_T500-1983':
+ case 'CSISO99NAPLPS':
+ case 'ISO-IR-99':
+ case 'NAPLPS':
+ return 'ANSI_X3.110-1983';
+
+ case 'ARABIC7':
+ case 'ASMO_449':
+ case 'CSISO89ASMO449':
+ case 'ISO-IR-89':
+ case 'ISO_9036':
+ return 'ASMO_449';
+
+ case 'ADOBE-STANDARD-ENCODING':
+ case 'CSADOBESTANDARDENCODING':
+ return 'Adobe-Standard-Encoding';
+
+ case 'ADOBE-SYMBOL-ENCODING':
+ case 'CSHPPSMATH':
+ return 'Adobe-Symbol-Encoding';
+
+ case 'AMI-1251':
+ case 'AMI1251':
+ case 'AMIGA-1251':
+ case 'AMIGA1251':
+ return 'Amiga-1251';
+
+ case 'BOCU-1':
+ case 'CSBOCU-1':
+ return 'BOCU-1';
+
+ case 'BRF':
+ case 'CSBRF':
+ return 'BRF';
+
+ case 'BS_4730':
+ case 'CSISO4UNITEDKINGDOM':
+ case 'GB':
+ case 'ISO-IR-4':
+ case 'ISO646-GB':
+ case 'UK':
+ return 'BS_4730';
+
+ case 'BS_VIEWDATA':
+ case 'CSISO47BSVIEWDATA':
+ case 'ISO-IR-47':
+ return 'BS_viewdata';
+
+ case 'BIG5':
+ case 'CSBIG5':
+ return 'Big5';
+
+ case 'BIG5-HKSCS':
+ return 'Big5-HKSCS';
+
+ case 'CESU-8':
+ case 'CSCESU-8':
+ return 'CESU-8';
+
+ case 'CA':
+ case 'CSA7-1':
+ case 'CSA_Z243.4-1985-1':
+ case 'CSISO121CANADIAN1':
+ case 'ISO-IR-121':
+ case 'ISO646-CA':
+ return 'CSA_Z243.4-1985-1';
+
+ case 'CSA7-2':
+ case 'CSA_Z243.4-1985-2':
+ case 'CSISO122CANADIAN2':
+ case 'ISO-IR-122':
+ case 'ISO646-CA2':
+ return 'CSA_Z243.4-1985-2';
+
+ case 'CSA_Z243.4-1985-GR':
+ case 'CSISO123CSAZ24341985GR':
+ case 'ISO-IR-123':
+ return 'CSA_Z243.4-1985-gr';
+
+ case 'CSISO139CSN369103':
+ case 'CSN_369103':
+ case 'ISO-IR-139':
+ return 'CSN_369103';
+
+ case 'CSDECMCS':
+ case 'DEC':
+ case 'DEC-MCS':
+ return 'DEC-MCS';
+
+ case 'CSISO21GERMAN':
+ case 'DE':
+ case 'DIN_66003':
+ case 'ISO-IR-21':
+ case 'ISO646-DE':
+ return 'DIN_66003';
+
+ case 'CSISO646DANISH':
+ case 'DK':
+ case 'DS2089':
+ case 'DS_2089':
+ case 'ISO646-DK':
+ return 'DS_2089';
+
+ case 'CSIBMEBCDICATDE':
+ case 'EBCDIC-AT-DE':
+ return 'EBCDIC-AT-DE';
+
+ case 'CSEBCDICATDEA':
+ case 'EBCDIC-AT-DE-A':
+ return 'EBCDIC-AT-DE-A';
+
+ case 'CSEBCDICCAFR':
+ case 'EBCDIC-CA-FR':
+ return 'EBCDIC-CA-FR';
+
+ case 'CSEBCDICDKNO':
+ case 'EBCDIC-DK-NO':
+ return 'EBCDIC-DK-NO';
+
+ case 'CSEBCDICDKNOA':
+ case 'EBCDIC-DK-NO-A':
+ return 'EBCDIC-DK-NO-A';
+
+ case 'CSEBCDICES':
+ case 'EBCDIC-ES':
+ return 'EBCDIC-ES';
+
+ case 'CSEBCDICESA':
+ case 'EBCDIC-ES-A':
+ return 'EBCDIC-ES-A';
+
+ case 'CSEBCDICESS':
+ case 'EBCDIC-ES-S':
+ return 'EBCDIC-ES-S';
+
+ case 'CSEBCDICFISE':
+ case 'EBCDIC-FI-SE':
+ return 'EBCDIC-FI-SE';
+
+ case 'CSEBCDICFISEA':
+ case 'EBCDIC-FI-SE-A':
+ return 'EBCDIC-FI-SE-A';
+
+ case 'CSEBCDICFR':
+ case 'EBCDIC-FR':
+ return 'EBCDIC-FR';
+
+ case 'CSEBCDICIT':
+ case 'EBCDIC-IT':
+ return 'EBCDIC-IT';
+
+ case 'CSEBCDICPT':
+ case 'EBCDIC-PT':
+ return 'EBCDIC-PT';
+
+ case 'CSEBCDICUK':
+ case 'EBCDIC-UK':
+ return 'EBCDIC-UK';
+
+ case 'CSEBCDICUS':
+ case 'EBCDIC-US':
+ return 'EBCDIC-US';
+
+ case 'CSISO111ECMACYRILLIC':
+ case 'ECMA-CYRILLIC':
+ case 'ISO-IR-111':
+ case 'KOI8-E':
+ return 'ECMA-cyrillic';
+
+ case 'CSISO17SPANISH':
+ case 'ES':
+ case 'ISO-IR-17':
+ case 'ISO646-ES':
+ return 'ES';
+
+ case 'CSISO85SPANISH2':
+ case 'ES2':
+ case 'ISO-IR-85':
+ case 'ISO646-ES2':
+ return 'ES2';
+
+ case 'CSEUCPKDFMTJAPANESE':
+ case 'EUC-JP':
+ case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
+ return 'EUC-JP';
+
+ case 'CSEUCKR':
+ case 'EUC-KR':
+ return 'EUC-KR';
+
+ case 'CSEUCFIXWIDJAPANESE':
+ case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
+ return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
+
+ case 'GB18030':
+ return 'GB18030';
+
+ case 'CSGB2312':
+ case 'GB2312':
+ return 'GB2312';
+
+ case 'CP936':
+ case 'GBK':
+ case 'MS936':
+ case 'WINDOWS-936':
+ return 'GBK';
+
+ case 'CN':
+ case 'CSISO57GB1988':
+ case 'GB_1988-80':
+ case 'ISO-IR-57':
+ case 'ISO646-CN':
+ return 'GB_1988-80';
+
+ case 'CHINESE':
+ case 'CSISO58GB231280':
+ case 'GB_2312-80':
+ case 'ISO-IR-58':
+ return 'GB_2312-80';
+
+ case 'CSISO153GOST1976874':
+ case 'GOST_19768-74':
+ case 'ISO-IR-153':
+ case 'ST_SEV_358-88':
+ return 'GOST_19768-74';
+
+ case 'CSHPDESKTOP':
+ case 'HP-DESKTOP':
+ return 'HP-DeskTop';
+
+ case 'CSHPLEGAL':
+ case 'HP-LEGAL':
+ return 'HP-Legal';
+
+ case 'CSHPMATH8':
+ case 'HP-MATH8':
+ return 'HP-Math8';
+
+ case 'CSHPPIFONT':
+ case 'HP-PI-FONT':
+ return 'HP-Pi-font';
+
+ case 'HZ-GB-2312':
+ return 'HZ-GB-2312';
+
+ case 'CSIBMSYMBOLS':
+ case 'IBM-SYMBOLS':
+ return 'IBM-Symbols';
+
+ case 'CSIBMTHAI':
+ case 'IBM-THAI':
+ return 'IBM-Thai';
+
+ case 'CCSID00858':
+ case 'CP00858':
+ case 'IBM00858':
+ case 'PC-MULTILINGUAL-850+EURO':
+ return 'IBM00858';
+
+ case 'CCSID00924':
+ case 'CP00924':
+ case 'EBCDIC-LATIN9--EURO':
+ case 'IBM00924':
+ return 'IBM00924';
+
+ case 'CCSID01140':
+ case 'CP01140':
+ case 'EBCDIC-US-37+EURO':
+ case 'IBM01140':
+ return 'IBM01140';
+
+ case 'CCSID01141':
+ case 'CP01141':
+ case 'EBCDIC-DE-273+EURO':
+ case 'IBM01141':
+ return 'IBM01141';
+
+ case 'CCSID01142':
+ case 'CP01142':
+ case 'EBCDIC-DK-277+EURO':
+ case 'EBCDIC-NO-277+EURO':
+ case 'IBM01142':
+ return 'IBM01142';
+
+ case 'CCSID01143':
+ case 'CP01143':
+ case 'EBCDIC-FI-278+EURO':
+ case 'EBCDIC-SE-278+EURO':
+ case 'IBM01143':
+ return 'IBM01143';
+
+ case 'CCSID01144':
+ case 'CP01144':
+ case 'EBCDIC-IT-280+EURO':
+ case 'IBM01144':
+ return 'IBM01144';
+
+ case 'CCSID01145':
+ case 'CP01145':
+ case 'EBCDIC-ES-284+EURO':
+ case 'IBM01145':
+ return 'IBM01145';
+
+ case 'CCSID01146':
+ case 'CP01146':
+ case 'EBCDIC-GB-285+EURO':
+ case 'IBM01146':
+ return 'IBM01146';
+
+ case 'CCSID01147':
+ case 'CP01147':
+ case 'EBCDIC-FR-297+EURO':
+ case 'IBM01147':
+ return 'IBM01147';
+
+ case 'CCSID01148':
+ case 'CP01148':
+ case 'EBCDIC-INTERNATIONAL-500+EURO':
+ case 'IBM01148':
+ return 'IBM01148';
+
+ case 'CCSID01149':
+ case 'CP01149':
+ case 'EBCDIC-IS-871+EURO':
+ case 'IBM01149':
+ return 'IBM01149';
+
+ case 'CP037':
+ case 'CSIBM037':
+ case 'EBCDIC-CP-CA':
+ case 'EBCDIC-CP-NL':
+ case 'EBCDIC-CP-US':
+ case 'EBCDIC-CP-WT':
+ case 'IBM037':
+ return 'IBM037';
+
+ case 'CP038':
+ case 'CSIBM038':
+ case 'EBCDIC-INT':
+ case 'IBM038':
+ return 'IBM038';
+
+ case 'CP1026':
+ case 'CSIBM1026':
+ case 'IBM1026':
+ return 'IBM1026';
+
+ case 'IBM-1047':
+ case 'IBM1047':
+ return 'IBM1047';
+
+ case 'CP273':
+ case 'CSIBM273':
+ case 'IBM273':
+ return 'IBM273';
+
+ case 'CP274':
+ case 'CSIBM274':
+ case 'EBCDIC-BE':
+ case 'IBM274':
+ return 'IBM274';
+
+ case 'CP275':
+ case 'CSIBM275':
+ case 'EBCDIC-BR':
+ case 'IBM275':
+ return 'IBM275';
+
+ case 'CSIBM277':
+ case 'EBCDIC-CP-DK':
+ case 'EBCDIC-CP-NO':
+ case 'IBM277':
+ return 'IBM277';
+
+ case 'CP278':
+ case 'CSIBM278':
+ case 'EBCDIC-CP-FI':
+ case 'EBCDIC-CP-SE':
+ case 'IBM278':
+ return 'IBM278';
+
+ case 'CP280':
+ case 'CSIBM280':
+ case 'EBCDIC-CP-IT':
+ case 'IBM280':
+ return 'IBM280';
+
+ case 'CP281':
+ case 'CSIBM281':
+ case 'EBCDIC-JP-E':
+ case 'IBM281':
+ return 'IBM281';
+
+ case 'CP284':
+ case 'CSIBM284':
+ case 'EBCDIC-CP-ES':
+ case 'IBM284':
+ return 'IBM284';
+
+ case 'CP285':
+ case 'CSIBM285':
+ case 'EBCDIC-CP-GB':
+ case 'IBM285':
+ return 'IBM285';
+
+ case 'CP290':
+ case 'CSIBM290':
+ case 'EBCDIC-JP-KANA':
+ case 'IBM290':
+ return 'IBM290';
+
+ case 'CP297':
+ case 'CSIBM297':
+ case 'EBCDIC-CP-FR':
+ case 'IBM297':
+ return 'IBM297';
+
+ case 'CP420':
+ case 'CSIBM420':
+ case 'EBCDIC-CP-AR1':
+ case 'IBM420':
+ return 'IBM420';
+
+ case 'CP423':
+ case 'CSIBM423':
+ case 'EBCDIC-CP-GR':
+ case 'IBM423':
+ return 'IBM423';
+
+ case 'CP424':
+ case 'CSIBM424':
+ case 'EBCDIC-CP-HE':
+ case 'IBM424':
+ return 'IBM424';
+
+ case '437':
+ case 'CP437':
+ case 'CSPC8CODEPAGE437':
+ case 'IBM437':
+ return 'IBM437';
+
+ case 'CP500':
+ case 'CSIBM500':
+ case 'EBCDIC-CP-BE':
+ case 'EBCDIC-CP-CH':
+ case 'IBM500':
+ return 'IBM500';
+
+ case 'CP775':
+ case 'CSPC775BALTIC':
+ case 'IBM775':
+ return 'IBM775';
+
+ case '850':
+ case 'CP850':
+ case 'CSPC850MULTILINGUAL':
+ case 'IBM850':
+ return 'IBM850';
+
+ case '851':
+ case 'CP851':
+ case 'CSIBM851':
+ case 'IBM851':
+ return 'IBM851';
+
+ case '852':
+ case 'CP852':
+ case 'CSPCP852':
+ case 'IBM852':
+ return 'IBM852';
+
+ case '855':
+ case 'CP855':
+ case 'CSIBM855':
+ case 'IBM855':
+ return 'IBM855';
+
+ case '857':
+ case 'CP857':
+ case 'CSIBM857':
+ case 'IBM857':
+ return 'IBM857';
+
+ case '860':
+ case 'CP860':
+ case 'CSIBM860':
+ case 'IBM860':
+ return 'IBM860';
+
+ case '861':
+ case 'CP-IS':
+ case 'CP861':
+ case 'CSIBM861':
+ case 'IBM861':
+ return 'IBM861';
+
+ case '862':
+ case 'CP862':
+ case 'CSPC862LATINHEBREW':
+ case 'IBM862':
+ return 'IBM862';
+
+ case '863':
+ case 'CP863':
+ case 'CSIBM863':
+ case 'IBM863':
+ return 'IBM863';
+
+ case 'CP864':
+ case 'CSIBM864':
+ case 'IBM864':
+ return 'IBM864';
+
+ case '865':
+ case 'CP865':
+ case 'CSIBM865':
+ case 'IBM865':
+ return 'IBM865';
+
+ case '866':
+ case 'CP866':
+ case 'CSIBM866':
+ case 'IBM866':
+ return 'IBM866';
+
+ case 'CP-AR':
+ case 'CP868':
+ case 'CSIBM868':
+ case 'IBM868':
+ return 'IBM868';
+
+ case '869':
+ case 'CP-GR':
+ case 'CP869':
+ case 'CSIBM869':
+ case 'IBM869':
+ return 'IBM869';
+
+ case 'CP870':
+ case 'CSIBM870':
+ case 'EBCDIC-CP-ROECE':
+ case 'EBCDIC-CP-YU':
+ case 'IBM870':
+ return 'IBM870';
+
+ case 'CP871':
+ case 'CSIBM871':
+ case 'EBCDIC-CP-IS':
+ case 'IBM871':
+ return 'IBM871';
+
+ case 'CP880':
+ case 'CSIBM880':
+ case 'EBCDIC-CYRILLIC':
+ case 'IBM880':
+ return 'IBM880';
+
+ case 'CP891':
+ case 'CSIBM891':
+ case 'IBM891':
+ return 'IBM891';
+
+ case 'CP903':
+ case 'CSIBM903':
+ case 'IBM903':
+ return 'IBM903';
+
+ case '904':
+ case 'CP904':
+ case 'CSIBBM904':
+ case 'IBM904':
+ return 'IBM904';
+
+ case 'CP905':
+ case 'CSIBM905':
+ case 'EBCDIC-CP-TR':
+ case 'IBM905':
+ return 'IBM905';
+
+ case 'CP918':
+ case 'CSIBM918':
+ case 'EBCDIC-CP-AR2':
+ case 'IBM918':
+ return 'IBM918';
+
+ case 'CSISO143IECP271':
+ case 'IEC_P27-1':
+ case 'ISO-IR-143':
+ return 'IEC_P27-1';
+
+ case 'CSISO49INIS':
+ case 'INIS':
+ case 'ISO-IR-49':
+ return 'INIS';
+
+ case 'CSISO50INIS8':
+ case 'INIS-8':
+ case 'ISO-IR-50':
+ return 'INIS-8';
+
+ case 'CSISO51INISCYRILLIC':
+ case 'INIS-CYRILLIC':
+ case 'ISO-IR-51':
+ return 'INIS-cyrillic';
+
+ case 'CSINVARIANT':
+ case 'INVARIANT':
+ return 'INVARIANT';
+
+ case 'ISO-10646-J-1':
+ return 'ISO-10646-J-1';
+
+ case 'CSUNICODE':
+ case 'ISO-10646-UCS-2':
+ return 'ISO-10646-UCS-2';
+
+ case 'CSUCS4':
+ case 'ISO-10646-UCS-4':
+ return 'ISO-10646-UCS-4';
+
+ case 'CSUNICODEASCII':
+ case 'ISO-10646-UCS-BASIC':
+ return 'ISO-10646-UCS-Basic';
+
+ case 'CSISO10646UTF1':
+ case 'ISO-10646-UTF-1':
+ return 'ISO-10646-UTF-1';
+
+ case 'CSUNICODELATIN1':
+ case 'ISO-10646':
+ case 'ISO-10646-UNICODE-LATIN1':
+ return 'ISO-10646-Unicode-Latin1';
+
+ case 'CSISO115481':
+ case 'ISO-11548-1':
+ case 'ISO_11548-1':
+ case 'ISO_TR_11548-1':
+ return 'ISO-11548-1';
+
+ case 'ISO-2022-CN':
+ return 'ISO-2022-CN';
+
+ case 'ISO-2022-CN-EXT':
+ return 'ISO-2022-CN-EXT';
+
+ case 'CSISO2022JP':
+ case 'ISO-2022-JP':
+ return 'ISO-2022-JP';
+
+ case 'CSISO2022JP2':
+ case 'ISO-2022-JP-2':
+ return 'ISO-2022-JP-2';
+
+ case 'CSISO2022KR':
+ case 'ISO-2022-KR':
+ return 'ISO-2022-KR';
+
+ case 'CSWINDOWS30LATIN1':
+ case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
+ return 'ISO-8859-1-Windows-3.0-Latin-1';
+
+ case 'CSWINDOWS31LATIN1':
+ case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
+ return 'ISO-8859-1-Windows-3.1-Latin-1';
+
+ case 'CSISOLATIN6':
+ case 'ISO-8859-10':
+ case 'ISO-IR-157':
+ case 'ISO_8859-10:1992':
+ case 'L6':
+ case 'LATIN6':
+ return 'ISO-8859-10';
+
+ case 'ISO-8859-13':
+ return 'ISO-8859-13';
+
+ case 'ISO-8859-14':
+ case 'ISO-CELTIC':
+ case 'ISO-IR-199':
+ case 'ISO_8859-14':
+ case 'ISO_8859-14:1998':
+ case 'L8':
+ case 'LATIN8':
+ return 'ISO-8859-14';
+
+ case 'ISO-8859-15':
+ case 'ISO_8859-15':
+ case 'LATIN-9':
+ return 'ISO-8859-15';
+
+ case 'ISO-8859-16':
+ case 'ISO-IR-226':
+ case 'ISO_8859-16':
+ case 'ISO_8859-16:2001':
+ case 'L10':
+ case 'LATIN10':
+ return 'ISO-8859-16';
+
+ case 'CSISOLATIN2':
+ case 'ISO-8859-2':
+ case 'ISO-IR-101':
+ case 'ISO_8859-2':
+ case 'ISO_8859-2:1987':
+ case 'L2':
+ case 'LATIN2':
+ return 'ISO-8859-2';
+
+ case 'CSWINDOWS31LATIN2':
+ case 'ISO-8859-2-WINDOWS-LATIN-2':
+ return 'ISO-8859-2-Windows-Latin-2';
+
+ case 'CSISOLATIN3':
+ case 'ISO-8859-3':
+ case 'ISO-IR-109':
+ case 'ISO_8859-3':
+ case 'ISO_8859-3:1988':
+ case 'L3':
+ case 'LATIN3':
+ return 'ISO-8859-3';
+
+ case 'CSISOLATIN4':
+ case 'ISO-8859-4':
+ case 'ISO-IR-110':
+ case 'ISO_8859-4':
+ case 'ISO_8859-4:1988':
+ case 'L4':
+ case 'LATIN4':
+ return 'ISO-8859-4';
+
+ case 'CSISOLATINCYRILLIC':
+ case 'CYRILLIC':
+ case 'ISO-8859-5':
+ case 'ISO-IR-144':
+ case 'ISO_8859-5':
+ case 'ISO_8859-5:1988':
+ return 'ISO-8859-5';
+
+ case 'ARABIC':
+ case 'ASMO-708':
+ case 'CSISOLATINARABIC':
+ case 'ECMA-114':
+ case 'ISO-8859-6':
+ case 'ISO-IR-127':
+ case 'ISO_8859-6':
+ case 'ISO_8859-6:1987':
+ return 'ISO-8859-6';
+
+ case 'CSISO88596E':
+ case 'ISO-8859-6-E':
+ case 'ISO_8859-6-E':
+ return 'ISO-8859-6-E';
+
+ case 'CSISO88596I':
+ case 'ISO-8859-6-I':
+ case 'ISO_8859-6-I':
+ return 'ISO-8859-6-I';
+
+ case 'CSISOLATINGREEK':
+ case 'ECMA-118':
+ case 'ELOT_928':
+ case 'GREEK':
+ case 'GREEK8':
+ case 'ISO-8859-7':
+ case 'ISO-IR-126':
+ case 'ISO_8859-7':
+ case 'ISO_8859-7:1987':
+ return 'ISO-8859-7';
+
+ case 'CSISOLATINHEBREW':
+ case 'HEBREW':
+ case 'ISO-8859-8':
+ case 'ISO-IR-138':
+ case 'ISO_8859-8':
+ case 'ISO_8859-8:1988':
+ return 'ISO-8859-8';
+
+ case 'CSISO88598E':
+ case 'ISO-8859-8-E':
+ case 'ISO_8859-8-E':
+ return 'ISO-8859-8-E';
+
+ case 'CSISO88598I':
+ case 'ISO-8859-8-I':
+ case 'ISO_8859-8-I':
+ return 'ISO-8859-8-I';
+
+ case 'CSISOLATIN5':
+ case 'ISO-8859-9':
+ case 'ISO-IR-148':
+ case 'ISO_8859-9':
+ case 'ISO_8859-9:1989':
+ case 'L5':
+ case 'LATIN5':
+ return 'ISO-8859-9';
+
+ case 'CSWINDOWS31LATIN5':
+ case 'ISO-8859-9-WINDOWS-LATIN-5':
+ return 'ISO-8859-9-Windows-Latin-5';
+
+ case 'CSUNICODEIBM1261':
+ case 'ISO-UNICODE-IBM-1261':
+ return 'ISO-Unicode-IBM-1261';
+
+ case 'CSUNICODEIBM1264':
+ case 'ISO-UNICODE-IBM-1264':
+ return 'ISO-Unicode-IBM-1264';
+
+ case 'CSUNICODEIBM1265':
+ case 'ISO-UNICODE-IBM-1265':
+ return 'ISO-Unicode-IBM-1265';
+
+ case 'CSUNICODEIBM1268':
+ case 'ISO-UNICODE-IBM-1268':
+ return 'ISO-Unicode-IBM-1268';
+
+ case 'CSUNICODEIBM1276':
+ case 'ISO-UNICODE-IBM-1276':
+ return 'ISO-Unicode-IBM-1276';
+
+ case 'CSISO10367BOX':
+ case 'ISO-IR-155':
+ case 'ISO_10367-BOX':
+ return 'ISO_10367-box';
+
+ case 'CSISO2033':
+ case 'E13B':
+ case 'ISO-IR-98':
+ case 'ISO_2033-1983':
+ return 'ISO_2033-1983';
+
+ case 'CSISO5427CYRILLIC':
+ case 'ISO-IR-37':
+ case 'ISO_5427':
+ return 'ISO_5427';
+
+ case 'ISO-IR-54':
+ case 'ISO5427CYRILLIC1981':
+ case 'ISO_5427:1981':
+ return 'ISO_5427:1981';
+
+ case 'CSISO5428GREEK':
+ case 'ISO-IR-55':
+ case 'ISO_5428:1980':
+ return 'ISO_5428:1980';
+
+ case 'CSISO646BASIC1983':
+ case 'ISO_646.BASIC:1983':
+ case 'REF':
+ return 'ISO_646.basic:1983';
+
+ case 'CSISO2INTLREFVERSION':
+ case 'IRV':
+ case 'ISO-IR-2':
+ case 'ISO_646.IRV:1983':
+ return 'ISO_646.irv:1983';
+
+ case 'CSISO6937ADD':
+ case 'ISO-IR-152':
+ case 'ISO_6937-2-25':
+ return 'ISO_6937-2-25';
+
+ case 'CSISOTEXTCOMM':
+ case 'ISO-IR-142':
+ case 'ISO_6937-2-ADD':
+ return 'ISO_6937-2-add';
+
+ case 'CSISO8859SUPP':
+ case 'ISO-IR-154':
+ case 'ISO_8859-SUPP':
+ case 'LATIN1-2-5':
+ return 'ISO_8859-supp';
+
+ case 'CSISO15ITALIAN':
+ case 'ISO-IR-15':
+ case 'ISO646-IT':
+ case 'IT':
+ return 'IT';
+
+ case 'CSISO13JISC6220JP':
+ case 'ISO-IR-13':
+ case 'JIS_C6220-1969':
+ case 'JIS_C6220-1969-JP':
+ case 'KATAKANA':
+ case 'X0201-7':
+ return 'JIS_C6220-1969-jp';
+
+ case 'CSISO14JISC6220RO':
+ case 'ISO-IR-14':
+ case 'ISO646-JP':
+ case 'JIS_C6220-1969-RO':
+ case 'JP':
+ return 'JIS_C6220-1969-ro';
+
+ case 'CSISO42JISC62261978':
+ case 'ISO-IR-42':
+ case 'JIS_C6226-1978':
+ return 'JIS_C6226-1978';
+
+ case 'CSISO87JISX0208':
+ case 'ISO-IR-87':
+ case 'JIS_C6226-1983':
+ case 'JIS_X0208-1983':
+ case 'X0208':
+ return 'JIS_C6226-1983';
+
+ case 'CSISO91JISC62291984A':
+ case 'ISO-IR-91':
+ case 'JIS_C6229-1984-A':
+ case 'JP-OCR-A':
+ return 'JIS_C6229-1984-a';
+
+ case 'CSISO92JISC62991984B':
+ case 'ISO-IR-92':
+ case 'ISO646-JP-OCR-B':
+ case 'JIS_C6229-1984-B':
+ case 'JP-OCR-B':
+ return 'JIS_C6229-1984-b';
+
+ case 'CSISO93JIS62291984BADD':
+ case 'ISO-IR-93':
+ case 'JIS_C6229-1984-B-ADD':
+ case 'JP-OCR-B-ADD':
+ return 'JIS_C6229-1984-b-add';
+
+ case 'CSISO94JIS62291984HAND':
+ case 'ISO-IR-94':
+ case 'JIS_C6229-1984-HAND':
+ case 'JP-OCR-HAND':
+ return 'JIS_C6229-1984-hand';
+
+ case 'CSISO95JIS62291984HANDADD':
+ case 'ISO-IR-95':
+ case 'JIS_C6229-1984-HAND-ADD':
+ case 'JP-OCR-HAND-ADD':
+ return 'JIS_C6229-1984-hand-add';
+
+ case 'CSISO96JISC62291984KANA':
+ case 'ISO-IR-96':
+ case 'JIS_C6229-1984-KANA':
+ return 'JIS_C6229-1984-kana';
+
+ case 'CSJISENCODING':
+ case 'JIS_ENCODING':
+ return 'JIS_Encoding';
+
+ case 'CSHALFWIDTHKATAKANA':
+ case 'JIS_X0201':
+ case 'X0201':
+ return 'JIS_X0201';
+
+ case 'CSISO159JISX02121990':
+ case 'ISO-IR-159':
+ case 'JIS_X0212-1990':
+ case 'X0212':
+ return 'JIS_X0212-1990';
+
+ case 'CSISO141JUSIB1002':
+ case 'ISO-IR-141':
+ case 'ISO646-YU':
+ case 'JS':
+ case 'JUS_I.B1.002':
+ case 'YU':
+ return 'JUS_I.B1.002';
+
+ case 'CSISO147MACEDONIAN':
+ case 'ISO-IR-147':
+ case 'JUS_I.B1.003-MAC':
+ case 'MACEDONIAN':
+ return 'JUS_I.B1.003-mac';
+
+ case 'CSISO146SERBIAN':
+ case 'ISO-IR-146':
+ case 'JUS_I.B1.003-SERB':
+ case 'SERBIAN':
+ return 'JUS_I.B1.003-serb';
+
+ case 'KOI7-SWITCHED':
+ return 'KOI7-switched';
+
+ case 'CSKOI8R':
+ case 'KOI8-R':
+ return 'KOI8-R';
+
+ case 'KOI8-U':
+ return 'KOI8-U';
+
+ case 'CSKSC5636':
+ case 'ISO646-KR':
+ case 'KSC5636':
+ return 'KSC5636';
+
+ case 'CSKSC56011987':
+ case 'ISO-IR-149':
+ case 'KOREAN':
+ case 'KSC_5601':
+ case 'KS_C_5601-1987':
+ case 'KS_C_5601-1989':
+ return 'KS_C_5601-1987';
+
+ case 'CSKZ1048':
+ case 'KZ-1048':
+ case 'RK1048':
+ case 'STRK1048-2002':
+ return 'KZ-1048';
+
+ case 'CSISO27LATINGREEK1':
+ case 'ISO-IR-27':
+ case 'LATIN-GREEK-1':
+ return 'Latin-greek-1';
+
+ case 'CSMNEM':
+ case 'MNEM':
+ return 'MNEM';
+
+ case 'CSMNEMONIC':
+ case 'MNEMONIC':
+ return 'MNEMONIC';
+
+ case 'CSISO86HUNGARIAN':
+ case 'HU':
+ case 'ISO-IR-86':
+ case 'ISO646-HU':
+ case 'MSZ_7795.3':
+ return 'MSZ_7795.3';
+
+ case 'CSMICROSOFTPUBLISHING':
+ case 'MICROSOFT-PUBLISHING':
+ return 'Microsoft-Publishing';
+
+ case 'CSNATSDANO':
+ case 'ISO-IR-9-1':
+ case 'NATS-DANO':
+ return 'NATS-DANO';
+
+ case 'CSNATSDANOADD':
+ case 'ISO-IR-9-2':
+ case 'NATS-DANO-ADD':
+ return 'NATS-DANO-ADD';
+
+ case 'CSNATSSEFI':
+ case 'ISO-IR-8-1':
+ case 'NATS-SEFI':
+ return 'NATS-SEFI';
+
+ case 'CSNATSSEFIADD':
+ case 'ISO-IR-8-2':
+ case 'NATS-SEFI-ADD':
+ return 'NATS-SEFI-ADD';
+
+ case 'CSISO151CUBA':
+ case 'CUBA':
+ case 'ISO-IR-151':
+ case 'ISO646-CU':
+ case 'NC_NC00-10:81':
+ return 'NC_NC00-10:81';
+
+ case 'CSISO69FRENCH':
+ case 'FR':
+ case 'ISO-IR-69':
+ case 'ISO646-FR':
+ case 'NF_Z_62-010':
+ return 'NF_Z_62-010';
+
+ case 'CSISO25FRENCH':
+ case 'ISO-IR-25':
+ case 'ISO646-FR1':
+ case 'NF_Z_62-010_(1973)':
+ return 'NF_Z_62-010_(1973)';
+
+ case 'CSISO60DANISHNORWEGIAN':
+ case 'CSISO60NORWEGIAN1':
+ case 'ISO-IR-60':
+ case 'ISO646-NO':
+ case 'NO':
+ case 'NS_4551-1':
+ return 'NS_4551-1';
+
+ case 'CSISO61NORWEGIAN2':
+ case 'ISO-IR-61':
+ case 'ISO646-NO2':
+ case 'NO2':
+ case 'NS_4551-2':
+ return 'NS_4551-2';
+
+ case 'OSD_EBCDIC_DF03_IRV':
+ return 'OSD_EBCDIC_DF03_IRV';
+
+ case 'OSD_EBCDIC_DF04_1':
+ return 'OSD_EBCDIC_DF04_1';
+
+ case 'OSD_EBCDIC_DF04_15':
+ return 'OSD_EBCDIC_DF04_15';
+
+ case 'CSPC8DANISHNORWEGIAN':
+ case 'PC8-DANISH-NORWEGIAN':
+ return 'PC8-Danish-Norwegian';
+
+ case 'CSPC8TURKISH':
+ case 'PC8-TURKISH':
+ return 'PC8-Turkish';
+
+ case 'CSISO16PORTUGUESE':
+ case 'ISO-IR-16':
+ case 'ISO646-PT':
+ case 'PT':
+ return 'PT';
+
+ case 'CSISO84PORTUGUESE2':
+ case 'ISO-IR-84':
+ case 'ISO646-PT2':
+ case 'PT2':
+ return 'PT2';
+
+ case 'CP154':
+ case 'CSPTCP154':
+ case 'CYRILLIC-ASIAN':
+ case 'PT154':
+ case 'PTCP154':
+ return 'PTCP154';
+
+ case 'SCSU':
+ return 'SCSU';
+
+ case 'CSISO10SWEDISH':
+ case 'FI':
+ case 'ISO-IR-10':
+ case 'ISO646-FI':
+ case 'ISO646-SE':
+ case 'SE':
+ case 'SEN_850200_B':
+ return 'SEN_850200_B';
+
+ case 'CSISO11SWEDISHFORNAMES':
+ case 'ISO-IR-11':
+ case 'ISO646-SE2':
+ case 'SE2':
+ case 'SEN_850200_C':
+ return 'SEN_850200_C';
+
+ case 'CSSHIFTJIS':
+ case 'MS_KANJI':
+ case 'SHIFT_JIS':
+ return 'Shift_JIS';
+
+ case 'CSISO128T101G2':
+ case 'ISO-IR-128':
+ case 'T.101-G2':
+ return 'T.101-G2';
+
+ case 'CSISO102T617BIT':
+ case 'ISO-IR-102':
+ case 'T.61-7BIT':
+ return 'T.61-7bit';
+
+ case 'CSISO103T618BIT':
+ case 'ISO-IR-103':
+ case 'T.61':
+ case 'T.61-8BIT':
+ return 'T.61-8bit';
+
+ case 'CSTSCII':
+ case 'TSCII':
+ return 'TSCII';
+
+ case 'CSUNICODE11':
+ case 'UNICODE-1-1':
+ return 'UNICODE-1-1';
+
+ case 'CSUNICODE11UTF7':
+ case 'UNICODE-1-1-UTF-7':
+ return 'UNICODE-1-1-UTF-7';
+
+ case 'CSUNKNOWN8BIT':
+ case 'UNKNOWN-8BIT':
+ return 'UNKNOWN-8BIT';
+
+ case 'ANSI':
+ case 'ANSI_X3.4-1968':
+ case 'ANSI_X3.4-1986':
+ case 'ASCII':
+ case 'CP367':
+ case 'CSASCII':
+ case 'IBM367':
+ case 'ISO-IR-6':
+ case 'ISO646-US':
+ case 'ISO_646.IRV:1991':
+ case 'US':
+ case 'US-ASCII':
+ return 'US-ASCII';
+
+ case 'UTF-16':
+ return 'UTF-16';
+
+ case 'UTF-16BE':
+ return 'UTF-16BE';
+
+ case 'UTF-16LE':
+ return 'UTF-16LE';
+
+ case 'UTF-32':
+ return 'UTF-32';
+
+ case 'UTF-32BE':
+ return 'UTF-32BE';
+
+ case 'UTF-32LE':
+ return 'UTF-32LE';
+
+ case 'UTF-7':
+ return 'UTF-7';
+
+ case 'UTF-8':
+ return 'UTF-8';
+
+ case 'CSVIQR':
+ case 'VIQR':
+ return 'VIQR';
+
+ case 'CSVISCII':
+ case 'VISCII':
+ return 'VISCII';
+
+ case 'CSVENTURAINTERNATIONAL':
+ case 'VENTURA-INTERNATIONAL':
+ return 'Ventura-International';
+
+ case 'CSVENTURAMATH':
+ case 'VENTURA-MATH':
+ return 'Ventura-Math';
+
+ case 'CSVENTURAUS':
+ case 'VENTURA-US':
+ return 'Ventura-US';
+
+ case 'CSWINDOWS31J':
+ case 'WINDOWS-31J':
+ return 'Windows-31J';
+
+ case 'CSDKUS':
+ case 'DK-US':
+ return 'dk-us';
+
+ case 'CSISO150':
+ case 'CSISO150GREEKCCITT':
+ case 'GREEK-CCITT':
+ case 'ISO-IR-150':
+ return 'greek-ccitt';
+
+ case 'CSISO88GREEK7':
+ case 'GREEK7':
+ case 'ISO-IR-88':
+ return 'greek7';
+
+ case 'CSISO18GREEK7OLD':
+ case 'GREEK7-OLD':
+ case 'ISO-IR-18':
+ return 'greek7-old';
+
+ case 'CSHPROMAN8':
+ case 'HP-ROMAN8':
+ case 'R8':
+ case 'ROMAN8':
+ return 'hp-roman8';
+
+ case 'CSISO90':
+ case 'ISO-IR-90':
+ return 'iso-ir-90';
+
+ case 'CSISO19LATINGREEK':
+ case 'ISO-IR-19':
+ case 'LATIN-GREEK':
+ return 'latin-greek';
+
+ case 'CSISO158LAP':
+ case 'ISO-IR-158':
+ case 'LAP':
+ case 'LATIN-LAP':
+ return 'latin-lap';
+
+ case 'CSMACINTOSH':
+ case 'MAC':
+ case 'MACINTOSH':
+ return 'macintosh';
+
+ case 'CSUSDK':
+ case 'US-DK':
+ return 'us-dk';
+
+ case 'CSISO70VIDEOTEXSUPP1':
+ case 'ISO-IR-70':
+ case 'VIDEOTEX-SUPPL':
+ return 'videotex-suppl';
+
+ case 'WINDOWS-1250':
+ return 'windows-1250';
+
+ case 'WINDOWS-1251':
+ return 'windows-1251';
+
+ case 'CP819':
+ case 'CSISOLATIN1':
+ case 'IBM819':
+ case 'ISO-8859-1':
+ case 'ISO-IR-100':
+ case 'ISO_8859-1':
+ case 'ISO_8859-1:1987':
+ case 'L1':
+ case 'LATIN1':
+ case 'WINDOWS-1252':
+ return 'windows-1252';
+
+ case 'WINDOWS-1253':
+ return 'windows-1253';
+
+ case 'WINDOWS-1254':
+ return 'windows-1254';
+
+ case 'WINDOWS-1255':
+ return 'windows-1255';
+
+ case 'WINDOWS-1256':
+ return 'windows-1256';
+
+ case 'WINDOWS-1257':
+ return 'windows-1257';
+
+ case 'WINDOWS-1258':
+ return 'windows-1258';
+
+ default:
+ return $encoding;
+ }
+ }
+
+ function get_curl_version()
+ {
+ if (is_array($curl = curl_version()))
+ {
+ $curl = $curl['version'];
+ }
+ elseif (substr($curl, 0, 5) == 'curl/')
+ {
+ $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
+ }
+ elseif (substr($curl, 0, 8) == 'libcurl/')
+ {
+ $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
+ }
+ else
+ {
+ $curl = 0;
+ }
+ return $curl;
+ }
+
+ function is_subclass_of($class1, $class2)
+ {
+ if (func_num_args() != 2)
+ {
+ trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
+ }
+ elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
+ {
+ return is_subclass_of($class1, $class2);
+ }
+ elseif (is_string($class1) && is_string($class2))
+ {
+ if (class_exists($class1))
+ {
+ if (class_exists($class2))
+ {
+ $class2 = strtolower($class2);
+ while ($class1 = strtolower(get_parent_class($class1)))
+ {
+ if ($class1 == $class2)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ else
+ {
+ trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Strip HTML comments
+ *
+ * @access public
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ function strip_comments($data)
+ {
+ $output = '';
+ while (($start = strpos($data, '', $start)) !== false)
+ {
+ $data = substr_replace($data, '', 0, $end + 3);
+ }
+ else
+ {
+ $data = '';
+ }
+ }
+ return $output . $data;
+ }
+
+ function parse_date($dt)
+ {
+ $parser = SimplePie_Parse_Date::get();
+ return $parser->parse($dt);
+ }
+
+ /**
+ * Decode HTML entities
+ *
+ * @static
+ * @access public
+ * @param string $data Input data
+ * @return string Output data
+ */
+ function entities_decode($data)
+ {
+ $decoder = new SimplePie_Decode_HTML_Entities($data);
+ return $decoder->parse();
+ }
+
+ /**
+ * Remove RFC822 comments
+ *
+ * @access public
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ function uncomment_rfc822($string)
+ {
+ $string = (string) $string;
+ $position = 0;
+ $length = strlen($string);
+ $depth = 0;
+
+ $output = '';
+
+ while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
+ {
+ $output .= substr($string, $position, $pos - $position);
+ $position = $pos + 1;
+ if ($string[$pos - 1] !== '\\')
+ {
+ $depth++;
+ while ($depth && $position < $length)
+ {
+ $position += strcspn($string, '()', $position);
+ if ($string[$position - 1] === '\\')
+ {
+ $position++;
+ continue;
+ }
+ elseif (isset($string[$position]))
+ {
+ switch ($string[$position])
+ {
+ case '(':
+ $depth++;
+ break;
+
+ case ')':
+ $depth--;
+ break;
+ }
+ $position++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ $output .= '(';
+ }
+ }
+ $output .= substr($string, $position);
+
+ return $output;
+ }
+
+ function parse_mime($mime)
+ {
+ if (($pos = strpos($mime, ';')) === false)
+ {
+ return trim($mime);
+ }
+ else
+ {
+ return trim(substr($mime, 0, $pos));
+ }
+ }
+
+ function htmlspecialchars_decode($string, $quote_style)
+ {
+ if (function_exists('htmlspecialchars_decode'))
+ {
+ return htmlspecialchars_decode($string, $quote_style);
+ }
+ else
+ {
+ return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
+ }
+ }
+
+ function atom_03_construct_type($attribs)
+ {
+ if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
+ {
+ $mode = SIMPLEPIE_CONSTRUCT_BASE64;
+ }
+ else
+ {
+ $mode = SIMPLEPIE_CONSTRUCT_NONE;
+ }
+ if (isset($attribs['']['type']))
+ {
+ switch (strtolower(trim($attribs['']['type'])))
+ {
+ case 'text':
+ case 'text/plain':
+ return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
+
+ case 'html':
+ case 'text/html':
+ return SIMPLEPIE_CONSTRUCT_HTML | $mode;
+
+ case 'xhtml':
+ case 'application/xhtml+xml':
+ return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
+
+ default:
+ return SIMPLEPIE_CONSTRUCT_NONE | $mode;
+ }
+ }
+ else
+ {
+ return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
+ }
+ }
+
+ function atom_10_construct_type($attribs)
+ {
+ if (isset($attribs['']['type']))
+ {
+ switch (strtolower(trim($attribs['']['type'])))
+ {
+ case 'text':
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+
+ case 'html':
+ return SIMPLEPIE_CONSTRUCT_HTML;
+
+ case 'xhtml':
+ return SIMPLEPIE_CONSTRUCT_XHTML;
+
+ default:
+ return SIMPLEPIE_CONSTRUCT_NONE;
+ }
+ }
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+ }
+
+ function atom_10_content_construct_type($attribs)
+ {
+ if (isset($attribs['']['type']))
+ {
+ $type = strtolower(trim($attribs['']['type']));
+ switch ($type)
+ {
+ case 'text':
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+
+ case 'html':
+ return SIMPLEPIE_CONSTRUCT_HTML;
+
+ case 'xhtml':
+ return SIMPLEPIE_CONSTRUCT_XHTML;
+ }
+ if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
+ {
+ return SIMPLEPIE_CONSTRUCT_NONE;
+ }
+ else
+ {
+ return SIMPLEPIE_CONSTRUCT_BASE64;
+ }
+ }
+ else
+ {
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+ }
+ }
+
+ function is_isegment_nz_nc($string)
+ {
+ return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);
+ }
+
+ function space_seperated_tokens($string)
+ {
+ $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
+ $string_length = strlen($string);
+
+ $position = strspn($string, $space_characters);
+ $tokens = array();
+
+ while ($position < $string_length)
+ {
+ $len = strcspn($string, $space_characters, $position);
+ $tokens[] = substr($string, $position, $len);
+ $position += $len;
+ $position += strspn($string, $space_characters, $position);
+ }
+
+ return $tokens;
+ }
+
+ function array_unique($array)
+ {
+ if (version_compare(PHP_VERSION, '5.2', '>='))
+ {
+ return array_unique($array);
+ }
+ else
+ {
+ $array = (array) $array;
+ $new_array = array();
+ $new_array_strings = array();
+ foreach ($array as $key => $value)
+ {
+ if (is_object($value))
+ {
+ if (method_exists($value, '__toString'))
+ {
+ $cmp = $value->__toString();
+ }
+ else
+ {
+ trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
+ }
+ }
+ elseif (is_array($value))
+ {
+ $cmp = (string) reset($value);
+ }
+ else
+ {
+ $cmp = (string) $value;
+ }
+ if (!in_array($cmp, $new_array_strings))
+ {
+ $new_array[$key] = $value;
+ $new_array_strings[] = $cmp;
+ }
+ }
+ return $new_array;
+ }
+ }
+
+ /**
+ * Converts a unicode codepoint to a UTF-8 character
+ *
+ * @static
+ * @access public
+ * @param int $codepoint Unicode codepoint
+ * @return string UTF-8 character
+ */
+ function codepoint_to_utf8($codepoint)
+ {
+ static $cache = array();
+ $codepoint = (int) $codepoint;
+ if (isset($cache[$codepoint]))
+ {
+ return $cache[$codepoint];
+ }
+ elseif ($codepoint < 0)
+ {
+ return $cache[$codepoint] = false;
+ }
+ else if ($codepoint <= 0x7f)
+ {
+ return $cache[$codepoint] = chr($codepoint);
+ }
+ else if ($codepoint <= 0x7ff)
+ {
+ return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
+ }
+ else if ($codepoint <= 0xffff)
+ {
+ return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
+ }
+ else if ($codepoint <= 0x10ffff)
+ {
+ return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
+ }
+ else
+ {
+ // U+FFFD REPLACEMENT CHARACTER
+ return $cache[$codepoint] = "\xEF\xBF\xBD";
+ }
+ }
+
+ /**
+ * Re-implementation of PHP 5's stripos()
+ *
+ * Returns the numeric position of the first occurrence of needle in the
+ * haystack string.
+ *
+ * @static
+ * @access string
+ * @param object $haystack
+ * @param string $needle Note that the needle may be a string of one or more
+ * characters. If needle is not a string, it is converted to an integer
+ * and applied as the ordinal value of a character.
+ * @param int $offset The optional offset parameter allows you to specify which
+ * character in haystack to start searching. The position returned is still
+ * relative to the beginning of haystack.
+ * @return bool If needle is not found, stripos() will return boolean false.
+ */
+ function stripos($haystack, $needle, $offset = 0)
+ {
+ if (function_exists('stripos'))
+ {
+ return stripos($haystack, $needle, $offset);
+ }
+ else
+ {
+ if (is_string($needle))
+ {
+ $needle = strtolower($needle);
+ }
+ elseif (is_int($needle) || is_bool($needle) || is_double($needle))
+ {
+ $needle = strtolower(chr($needle));
+ }
+ else
+ {
+ trigger_error('needle is not a string or an integer', E_USER_WARNING);
+ return false;
+ }
+
+ return strpos(strtolower($haystack), $needle, $offset);
+ }
+ }
+
+ /**
+ * Similar to parse_str()
+ *
+ * Returns an associative array of name/value pairs, where the value is an
+ * array of values that have used the same name
+ *
+ * @static
+ * @access string
+ * @param string $str The input string.
+ * @return array
+ */
+ function parse_str($str)
+ {
+ $return = array();
+ $str = explode('&', $str);
+
+ foreach ($str as $section)
+ {
+ if (strpos($section, '=') !== false)
+ {
+ list($name, $value) = explode('=', $section, 2);
+ $return[urldecode($name)][] = urldecode($value);
+ }
+ else
+ {
+ $return[urldecode($section)][] = null;
+ }
+ }
+
+ return $return;
+ }
+
+ /**
+ * Detect XML encoding, as per XML 1.0 Appendix F.1
+ *
+ * @todo Add support for EBCDIC
+ * @param string $data XML data
+ * @return array Possible encodings
+ */
+ function xml_encoding($data)
+ {
+ // UTF-32 Big Endian BOM
+ if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
+ {
+ $encoding[] = 'UTF-32BE';
+ }
+ // UTF-32 Little Endian BOM
+ elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
+ {
+ $encoding[] = 'UTF-32LE';
+ }
+ // UTF-16 Big Endian BOM
+ elseif (substr($data, 0, 2) === "\xFE\xFF")
+ {
+ $encoding[] = 'UTF-16BE';
+ }
+ // UTF-16 Little Endian BOM
+ elseif (substr($data, 0, 2) === "\xFF\xFE")
+ {
+ $encoding[] = 'UTF-16LE';
+ }
+ // UTF-8 BOM
+ elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
+ {
+ $encoding[] = 'UTF-8';
+ }
+ // UTF-32 Big Endian Without BOM
+ elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
+ {
+ if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
+ {
+ $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-32BE';
+ }
+ // UTF-32 Little Endian Without BOM
+ elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
+ {
+ if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
+ {
+ $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-32LE';
+ }
+ // UTF-16 Big Endian Without BOM
+ elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
+ {
+ if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
+ {
+ $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-16BE';
+ }
+ // UTF-16 Little Endian Without BOM
+ elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
+ {
+ if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
+ {
+ $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-16LE';
+ }
+ // US-ASCII (or superset)
+ elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
+ {
+ if ($pos = strpos($data, "\x3F\x3E"))
+ {
+ $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-8';
+ }
+ // Fallback to UTF-8
+ else
+ {
+ $encoding[] = 'UTF-8';
+ }
+ return $encoding;
+ }
+}
+
+/**
+ * Decode HTML Entities
+ *
+ * This implements HTML5 as of revision 967 (2007-06-28)
+ *
+ * @package SimplePie
+ */
+class SimplePie_Decode_HTML_Entities
+{
+ /**
+ * Data to be parsed
+ *
+ * @access private
+ * @var string
+ */
+ var $data = '';
+
+ /**
+ * Currently consumed bytes
+ *
+ * @access private
+ * @var string
+ */
+ var $consumed = '';
+
+ /**
+ * Position of the current byte being parsed
+ *
+ * @access private
+ * @var int
+ */
+ var $position = 0;
+
+ /**
+ * Create an instance of the class with the input data
+ *
+ * @access public
+ * @param string $data Input data
+ */
+ function SimplePie_Decode_HTML_Entities($data)
+ {
+ $this->data = $data;
+ }
+
+ /**
+ * Parse the input data
+ *
+ * @access public
+ * @return string Output data
+ */
+ function parse()
+ {
+ while (($this->position = strpos($this->data, '&', $this->position)) !== false)
+ {
+ $this->consume();
+ $this->entity();
+ $this->consumed = '';
+ }
+ return $this->data;
+ }
+
+ /**
+ * Consume the next byte
+ *
+ * @access private
+ * @return mixed The next byte, or false, if there is no more data
+ */
+ function consume()
+ {
+ if (isset($this->data[$this->position]))
+ {
+ $this->consumed .= $this->data[$this->position];
+ return $this->data[$this->position++];
+ }
+ else
+ {
+ $this->consumed = false;
+ return false;
+ }
+ }
+
+ /**
+ * Consume a range of characters
+ *
+ * @access private
+ * @param string $chars Characters to consume
+ * @return mixed A series of characters that match the range, or false
+ */
+ function consume_range($chars)
+ {
+ if ($len = strspn($this->data, $chars, $this->position))
+ {
+ $data = substr($this->data, $this->position, $len);
+ $this->consumed .= $data;
+ $this->position += $len;
+ return $data;
+ }
+ else
+ {
+ $this->consumed = false;
+ return false;
+ }
+ }
+
+ /**
+ * Unconsume one byte
+ *
+ * @access private
+ */
+ function unconsume()
+ {
+ $this->consumed = substr($this->consumed, 0, -1);
+ $this->position--;
+ }
+
+ /**
+ * Decode an entity
+ *
+ * @access private
+ */
+ function entity()
+ {
+ switch ($this->consume())
+ {
+ case "\x09":
+ case "\x0A":
+ case "\x0B":
+ case "\x0B":
+ case "\x0C":
+ case "\x20":
+ case "\x3C":
+ case "\x26":
+ case false:
+ break;
+
+ case "\x23":
+ switch ($this->consume())
+ {
+ case "\x78":
+ case "\x58":
+ $range = '0123456789ABCDEFabcdef';
+ $hex = true;
+ break;
+
+ default:
+ $range = '0123456789';
+ $hex = false;
+ $this->unconsume();
+ break;
+ }
+
+ if ($codepoint = $this->consume_range($range))
+ {
+ static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
+
+ if ($hex)
+ {
+ $codepoint = hexdec($codepoint);
+ }
+ else
+ {
+ $codepoint = intval($codepoint);
+ }
+
+ if (isset($windows_1252_specials[$codepoint]))
+ {
+ $replacement = $windows_1252_specials[$codepoint];
+ }
+ else
+ {
+ $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
+ }
+
+ if ($this->consume() != ';')
+ {
+ $this->unconsume();
+ }
+
+ $consumed_length = strlen($this->consumed);
+ $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
+ $this->position += strlen($replacement) - $consumed_length;
+ }
+ break;
+
+ default:
+ static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C");
+
+ for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
+ {
+ $consumed = substr($this->consumed, 1);
+ if (isset($entities[$consumed]))
+ {
+ $match = $consumed;
+ }
+ }
+
+ if ($match !== null)
+ {
+ $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
+ $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
+ }
+ break;
+ }
+ }
+}
+
+/**
+ * Date Parser
+ *
+ * @package SimplePie
+ */
+class SimplePie_Parse_Date
+{
+ /**
+ * Input data
+ *
+ * @access protected
+ * @var string
+ */
+ var $date;
+
+ /**
+ * List of days, calendar day name => ordinal day number in the week
+ *
+ * @access protected
+ * @var array
+ */
+ var $day = array(
+ // English
+ 'mon' => 1,
+ 'monday' => 1,
+ 'tue' => 2,
+ 'tuesday' => 2,
+ 'wed' => 3,
+ 'wednesday' => 3,
+ 'thu' => 4,
+ 'thursday' => 4,
+ 'fri' => 5,
+ 'friday' => 5,
+ 'sat' => 6,
+ 'saturday' => 6,
+ 'sun' => 7,
+ 'sunday' => 7,
+ // Dutch
+ 'maandag' => 1,
+ 'dinsdag' => 2,
+ 'woensdag' => 3,
+ 'donderdag' => 4,
+ 'vrijdag' => 5,
+ 'zaterdag' => 6,
+ 'zondag' => 7,
+ // French
+ 'lundi' => 1,
+ 'mardi' => 2,
+ 'mercredi' => 3,
+ 'jeudi' => 4,
+ 'vendredi' => 5,
+ 'samedi' => 6,
+ 'dimanche' => 7,
+ // German
+ 'montag' => 1,
+ 'dienstag' => 2,
+ 'mittwoch' => 3,
+ 'donnerstag' => 4,
+ 'freitag' => 5,
+ 'samstag' => 6,
+ 'sonnabend' => 6,
+ 'sonntag' => 7,
+ // Italian
+ 'lunedì' => 1,
+ 'martedì' => 2,
+ 'mercoledì' => 3,
+ 'giovedì' => 4,
+ 'venerdì' => 5,
+ 'sabato' => 6,
+ 'domenica' => 7,
+ // Spanish
+ 'lunes' => 1,
+ 'martes' => 2,
+ 'miércoles' => 3,
+ 'jueves' => 4,
+ 'viernes' => 5,
+ 'sábado' => 6,
+ 'domingo' => 7,
+ // Finnish
+ 'maanantai' => 1,
+ 'tiistai' => 2,
+ 'keskiviikko' => 3,
+ 'torstai' => 4,
+ 'perjantai' => 5,
+ 'lauantai' => 6,
+ 'sunnuntai' => 7,
+ // Hungarian
+ 'hétfő' => 1,
+ 'kedd' => 2,
+ 'szerda' => 3,
+ 'csütörtok' => 4,
+ 'péntek' => 5,
+ 'szombat' => 6,
+ 'vasárnap' => 7,
+ // Greek
+ 'Δευ' => 1,
+ 'Τρι' => 2,
+ 'Τετ' => 3,
+ 'Πεμ' => 4,
+ 'Παρ' => 5,
+ 'Σαβ' => 6,
+ 'Κυρ' => 7,
+ );
+
+ /**
+ * List of months, calendar month name => calendar month number
+ *
+ * @access protected
+ * @var array
+ */
+ var $month = array(
+ // English
+ 'jan' => 1,
+ 'january' => 1,
+ 'feb' => 2,
+ 'february' => 2,
+ 'mar' => 3,
+ 'march' => 3,
+ 'apr' => 4,
+ 'april' => 4,
+ 'may' => 5,
+ // No long form of May
+ 'jun' => 6,
+ 'june' => 6,
+ 'jul' => 7,
+ 'july' => 7,
+ 'aug' => 8,
+ 'august' => 8,
+ 'sep' => 9,
+ 'september' => 8,
+ 'oct' => 10,
+ 'october' => 10,
+ 'nov' => 11,
+ 'november' => 11,
+ 'dec' => 12,
+ 'december' => 12,
+ // Dutch
+ 'januari' => 1,
+ 'februari' => 2,
+ 'maart' => 3,
+ 'april' => 4,
+ 'mei' => 5,
+ 'juni' => 6,
+ 'juli' => 7,
+ 'augustus' => 8,
+ 'september' => 9,
+ 'oktober' => 10,
+ 'november' => 11,
+ 'december' => 12,
+ // French
+ 'janvier' => 1,
+ 'février' => 2,
+ 'mars' => 3,
+ 'avril' => 4,
+ 'mai' => 5,
+ 'juin' => 6,
+ 'juillet' => 7,
+ 'août' => 8,
+ 'septembre' => 9,
+ 'octobre' => 10,
+ 'novembre' => 11,
+ 'décembre' => 12,
+ // German
+ 'januar' => 1,
+ 'februar' => 2,
+ 'märz' => 3,
+ 'april' => 4,
+ 'mai' => 5,
+ 'juni' => 6,
+ 'juli' => 7,
+ 'august' => 8,
+ 'september' => 9,
+ 'oktober' => 10,
+ 'november' => 11,
+ 'dezember' => 12,
+ // Italian
+ 'gennaio' => 1,
+ 'febbraio' => 2,
+ 'marzo' => 3,
+ 'aprile' => 4,
+ 'maggio' => 5,
+ 'giugno' => 6,
+ 'luglio' => 7,
+ 'agosto' => 8,
+ 'settembre' => 9,
+ 'ottobre' => 10,
+ 'novembre' => 11,
+ 'dicembre' => 12,
+ // Spanish
+ 'enero' => 1,
+ 'febrero' => 2,
+ 'marzo' => 3,
+ 'abril' => 4,
+ 'mayo' => 5,
+ 'junio' => 6,
+ 'julio' => 7,
+ 'agosto' => 8,
+ 'septiembre' => 9,
+ 'setiembre' => 9,
+ 'octubre' => 10,
+ 'noviembre' => 11,
+ 'diciembre' => 12,
+ // Finnish
+ 'tammikuu' => 1,
+ 'helmikuu' => 2,
+ 'maaliskuu' => 3,
+ 'huhtikuu' => 4,
+ 'toukokuu' => 5,
+ 'kesäkuu' => 6,
+ 'heinäkuu' => 7,
+ 'elokuu' => 8,
+ 'suuskuu' => 9,
+ 'lokakuu' => 10,
+ 'marras' => 11,
+ 'joulukuu' => 12,
+ // Hungarian
+ 'január' => 1,
+ 'február' => 2,
+ 'március' => 3,
+ 'április' => 4,
+ 'május' => 5,
+ 'június' => 6,
+ 'július' => 7,
+ 'augusztus' => 8,
+ 'szeptember' => 9,
+ 'október' => 10,
+ 'november' => 11,
+ 'december' => 12,
+ // Greek
+ 'Ιαν' => 1,
+ 'Φεβ' => 2,
+ 'Μάώ' => 3,
+ 'Μαώ' => 3,
+ 'Απρ' => 4,
+ 'Μάι' => 5,
+ 'Μαϊ' => 5,
+ 'Μαι' => 5,
+ 'Ιούν' => 6,
+ 'Ιον' => 6,
+ 'Ιούλ' => 7,
+ 'Ιολ' => 7,
+ 'Αύγ' => 8,
+ 'Αυγ' => 8,
+ 'Σεπ' => 9,
+ 'Οκτ' => 10,
+ 'Νοέ' => 11,
+ 'Δεκ' => 12,
+ );
+
+ /**
+ * List of timezones, abbreviation => offset from UTC
+ *
+ * @access protected
+ * @var array
+ */
+ var $timezone = array(
+ 'ACDT' => 37800,
+ 'ACIT' => 28800,
+ 'ACST' => 34200,
+ 'ACT' => -18000,
+ 'ACWDT' => 35100,
+ 'ACWST' => 31500,
+ 'AEDT' => 39600,
+ 'AEST' => 36000,
+ 'AFT' => 16200,
+ 'AKDT' => -28800,
+ 'AKST' => -32400,
+ 'AMDT' => 18000,
+ 'AMT' => -14400,
+ 'ANAST' => 46800,
+ 'ANAT' => 43200,
+ 'ART' => -10800,
+ 'AZOST' => -3600,
+ 'AZST' => 18000,
+ 'AZT' => 14400,
+ 'BIOT' => 21600,
+ 'BIT' => -43200,
+ 'BOT' => -14400,
+ 'BRST' => -7200,
+ 'BRT' => -10800,
+ 'BST' => 3600,
+ 'BTT' => 21600,
+ 'CAST' => 18000,
+ 'CAT' => 7200,
+ 'CCT' => 23400,
+ 'CDT' => -18000,
+ 'CEDT' => 7200,
+ 'CET' => 3600,
+ 'CGST' => -7200,
+ 'CGT' => -10800,
+ 'CHADT' => 49500,
+ 'CHAST' => 45900,
+ 'CIST' => -28800,
+ 'CKT' => -36000,
+ 'CLDT' => -10800,
+ 'CLST' => -14400,
+ 'COT' => -18000,
+ 'CST' => -21600,
+ 'CVT' => -3600,
+ 'CXT' => 25200,
+ 'DAVT' => 25200,
+ 'DTAT' => 36000,
+ 'EADT' => -18000,
+ 'EAST' => -21600,
+ 'EAT' => 10800,
+ 'ECT' => -18000,
+ 'EDT' => -14400,
+ 'EEST' => 10800,
+ 'EET' => 7200,
+ 'EGT' => -3600,
+ 'EKST' => 21600,
+ 'EST' => -18000,
+ 'FJT' => 43200,
+ 'FKDT' => -10800,
+ 'FKST' => -14400,
+ 'FNT' => -7200,
+ 'GALT' => -21600,
+ 'GEDT' => 14400,
+ 'GEST' => 10800,
+ 'GFT' => -10800,
+ 'GILT' => 43200,
+ 'GIT' => -32400,
+ 'GST' => 14400,
+ 'GST' => -7200,
+ 'GYT' => -14400,
+ 'HAA' => -10800,
+ 'HAC' => -18000,
+ 'HADT' => -32400,
+ 'HAE' => -14400,
+ 'HAP' => -25200,
+ 'HAR' => -21600,
+ 'HAST' => -36000,
+ 'HAT' => -9000,
+ 'HAY' => -28800,
+ 'HKST' => 28800,
+ 'HMT' => 18000,
+ 'HNA' => -14400,
+ 'HNC' => -21600,
+ 'HNE' => -18000,
+ 'HNP' => -28800,
+ 'HNR' => -25200,
+ 'HNT' => -12600,
+ 'HNY' => -32400,
+ 'IRDT' => 16200,
+ 'IRKST' => 32400,
+ 'IRKT' => 28800,
+ 'IRST' => 12600,
+ 'JFDT' => -10800,
+ 'JFST' => -14400,
+ 'JST' => 32400,
+ 'KGST' => 21600,
+ 'KGT' => 18000,
+ 'KOST' => 39600,
+ 'KOVST' => 28800,
+ 'KOVT' => 25200,
+ 'KRAST' => 28800,
+ 'KRAT' => 25200,
+ 'KST' => 32400,
+ 'LHDT' => 39600,
+ 'LHST' => 37800,
+ 'LINT' => 50400,
+ 'LKT' => 21600,
+ 'MAGST' => 43200,
+ 'MAGT' => 39600,
+ 'MAWT' => 21600,
+ 'MDT' => -21600,
+ 'MESZ' => 7200,
+ 'MEZ' => 3600,
+ 'MHT' => 43200,
+ 'MIT' => -34200,
+ 'MNST' => 32400,
+ 'MSDT' => 14400,
+ 'MSST' => 10800,
+ 'MST' => -25200,
+ 'MUT' => 14400,
+ 'MVT' => 18000,
+ 'MYT' => 28800,
+ 'NCT' => 39600,
+ 'NDT' => -9000,
+ 'NFT' => 41400,
+ 'NMIT' => 36000,
+ 'NOVST' => 25200,
+ 'NOVT' => 21600,
+ 'NPT' => 20700,
+ 'NRT' => 43200,
+ 'NST' => -12600,
+ 'NUT' => -39600,
+ 'NZDT' => 46800,
+ 'NZST' => 43200,
+ 'OMSST' => 25200,
+ 'OMST' => 21600,
+ 'PDT' => -25200,
+ 'PET' => -18000,
+ 'PETST' => 46800,
+ 'PETT' => 43200,
+ 'PGT' => 36000,
+ 'PHOT' => 46800,
+ 'PHT' => 28800,
+ 'PKT' => 18000,
+ 'PMDT' => -7200,
+ 'PMST' => -10800,
+ 'PONT' => 39600,
+ 'PST' => -28800,
+ 'PWT' => 32400,
+ 'PYST' => -10800,
+ 'PYT' => -14400,
+ 'RET' => 14400,
+ 'ROTT' => -10800,
+ 'SAMST' => 18000,
+ 'SAMT' => 14400,
+ 'SAST' => 7200,
+ 'SBT' => 39600,
+ 'SCDT' => 46800,
+ 'SCST' => 43200,
+ 'SCT' => 14400,
+ 'SEST' => 3600,
+ 'SGT' => 28800,
+ 'SIT' => 28800,
+ 'SRT' => -10800,
+ 'SST' => -39600,
+ 'SYST' => 10800,
+ 'SYT' => 7200,
+ 'TFT' => 18000,
+ 'THAT' => -36000,
+ 'TJT' => 18000,
+ 'TKT' => -36000,
+ 'TMT' => 18000,
+ 'TOT' => 46800,
+ 'TPT' => 32400,
+ 'TRUT' => 36000,
+ 'TVT' => 43200,
+ 'TWT' => 28800,
+ 'UYST' => -7200,
+ 'UYT' => -10800,
+ 'UZT' => 18000,
+ 'VET' => -14400,
+ 'VLAST' => 39600,
+ 'VLAT' => 36000,
+ 'VOST' => 21600,
+ 'VUT' => 39600,
+ 'WAST' => 7200,
+ 'WAT' => 3600,
+ 'WDT' => 32400,
+ 'WEST' => 3600,
+ 'WFT' => 43200,
+ 'WIB' => 25200,
+ 'WIT' => 32400,
+ 'WITA' => 28800,
+ 'WKST' => 18000,
+ 'WST' => 28800,
+ 'YAKST' => 36000,
+ 'YAKT' => 32400,
+ 'YAPT' => 36000,
+ 'YEKST' => 21600,
+ 'YEKT' => 18000,
+ );
+
+ /**
+ * Cached PCRE for SimplePie_Parse_Date::$day
+ *
+ * @access protected
+ * @var string
+ */
+ var $day_pcre;
+
+ /**
+ * Cached PCRE for SimplePie_Parse_Date::$month
+ *
+ * @access protected
+ * @var string
+ */
+ var $month_pcre;
+
+ /**
+ * Array of user-added callback methods
+ *
+ * @access private
+ * @var array
+ */
+ var $built_in = array();
+
+ /**
+ * Array of user-added callback methods
+ *
+ * @access private
+ * @var array
+ */
+ var $user = array();
+
+ /**
+ * Create new SimplePie_Parse_Date object, and set self::day_pcre,
+ * self::month_pcre, and self::built_in
+ *
+ * @access private
+ */
+ function SimplePie_Parse_Date()
+ {
+ $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
+ $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
+
+ static $cache;
+ if (!isset($cache[get_class($this)]))
+ {
+ if (extension_loaded('Reflection'))
+ {
+ $class = new ReflectionClass(get_class($this));
+ $methods = $class->getMethods();
+ $all_methods = array();
+ foreach ($methods as $method)
+ {
+ $all_methods[] = $method->getName();
+ }
+ }
+ else
+ {
+ $all_methods = get_class_methods($this);
+ }
+
+ foreach ($all_methods as $method)
+ {
+ if (strtolower(substr($method, 0, 5)) === 'date_')
+ {
+ $cache[get_class($this)][] = $method;
+ }
+ }
+ }
+
+ foreach ($cache[get_class($this)] as $method)
+ {
+ $this->built_in[] = $method;
+ }
+ }
+
+ /**
+ * Get the object
+ *
+ * @access public
+ */
+ function get()
+ {
+ static $object;
+ if (!$object)
+ {
+ $object = new SimplePie_Parse_Date;
+ }
+ return $object;
+ }
+
+ /**
+ * Parse a date
+ *
+ * @final
+ * @access public
+ * @param string $date Date to parse
+ * @return int Timestamp corresponding to date string, or false on failure
+ */
+ function parse($date)
+ {
+ foreach ($this->user as $method)
+ {
+ if (($returned = call_user_func($method, $date)) !== false)
+ {
+ return $returned;
+ }
+ }
+
+ foreach ($this->built_in as $method)
+ {
+ if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
+ {
+ return $returned;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Add a callback method to parse a date
+ *
+ * @final
+ * @access public
+ * @param callback $callback
+ */
+ function add_callback($callback)
+ {
+ if (is_callable($callback))
+ {
+ $this->user[] = $callback;
+ }
+ else
+ {
+ trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
+ }
+ }
+
+ /**
+ * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
+ * well as allowing any of upper or lower case "T", horizontal tabs, or
+ * spaces to be used as the time seperator (including more than one))
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_w3cdtf($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $year = '([0-9]{4})';
+ $month = $day = $hour = $minute = $second = '([0-9]{2})';
+ $decimal = '([0-9]*)';
+ $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
+ $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
+ }
+ if (preg_match($pcre, $date, $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Year
+ 2: Month
+ 3: Day
+ 4: Hour
+ 5: Minute
+ 6: Second
+ 7: Decimal fraction of a second
+ 8: Zulu
+ 9: Timezone ±
+ 10: Timezone hours
+ 11: Timezone minutes
+ */
+
+ // Fill in empty matches
+ for ($i = count($match); $i <= 3; $i++)
+ {
+ $match[$i] = '1';
+ }
+
+ for ($i = count($match); $i <= 7; $i++)
+ {
+ $match[$i] = '0';
+ }
+
+ // Numeric timezone
+ if (isset($match[9]) && $match[9] !== '')
+ {
+ $timezone = $match[10] * 3600;
+ $timezone += $match[11] * 60;
+ if ($match[9] === '-')
+ {
+ $timezone = 0 - $timezone;
+ }
+ }
+ else
+ {
+ $timezone = 0;
+ }
+
+ // Convert the number of seconds to an integer, taking decimals into account
+ $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
+
+ return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Remove RFC822 comments
+ *
+ * @access protected
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ function remove_rfc2822_comments($string)
+ {
+ $string = (string) $string;
+ $position = 0;
+ $length = strlen($string);
+ $depth = 0;
+
+ $output = '';
+
+ while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
+ {
+ $output .= substr($string, $position, $pos - $position);
+ $position = $pos + 1;
+ if ($string[$pos - 1] !== '\\')
+ {
+ $depth++;
+ while ($depth && $position < $length)
+ {
+ $position += strcspn($string, '()', $position);
+ if ($string[$position - 1] === '\\')
+ {
+ $position++;
+ continue;
+ }
+ elseif (isset($string[$position]))
+ {
+ switch ($string[$position])
+ {
+ case '(':
+ $depth++;
+ break;
+
+ case ')':
+ $depth--;
+ break;
+ }
+ $position++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ $output .= '(';
+ }
+ }
+ $output .= substr($string, $position);
+
+ return $output;
+ }
+
+ /**
+ * Parse RFC2822's date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_rfc2822($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $wsp = '[\x09\x20]';
+ $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
+ $optional_fws = $fws . '?';
+ $day_name = $this->day_pcre;
+ $month = $this->month_pcre;
+ $day = '([0-9]{1,2})';
+ $hour = $minute = $second = '([0-9]{2})';
+ $year = '([0-9]{2,4})';
+ $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
+ $character_zone = '([A-Z]{1,5})';
+ $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
+ $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
+ }
+ if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Day name
+ 2: Day
+ 3: Month
+ 4: Year
+ 5: Hour
+ 6: Minute
+ 7: Second
+ 8: Timezone ±
+ 9: Timezone hours
+ 10: Timezone minutes
+ 11: Alphabetic timezone
+ */
+
+ // Find the month number
+ $month = $this->month[strtolower($match[3])];
+
+ // Numeric timezone
+ if ($match[8] !== '')
+ {
+ $timezone = $match[9] * 3600;
+ $timezone += $match[10] * 60;
+ if ($match[8] === '-')
+ {
+ $timezone = 0 - $timezone;
+ }
+ }
+ // Character timezone
+ elseif (isset($this->timezone[strtoupper($match[11])]))
+ {
+ $timezone = $this->timezone[strtoupper($match[11])];
+ }
+ // Assume everything else to be -0000
+ else
+ {
+ $timezone = 0;
+ }
+
+ // Deal with 2/3 digit years
+ if ($match[4] < 50)
+ {
+ $match[4] += 2000;
+ }
+ elseif ($match[4] < 1000)
+ {
+ $match[4] += 1900;
+ }
+
+ // Second is optional, if it is empty set it to zero
+ if ($match[7] !== '')
+ {
+ $second = $match[7];
+ }
+ else
+ {
+ $second = 0;
+ }
+
+ return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Parse RFC850's date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_rfc850($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $space = '[\x09\x20]+';
+ $day_name = $this->day_pcre;
+ $month = $this->month_pcre;
+ $day = '([0-9]{1,2})';
+ $year = $hour = $minute = $second = '([0-9]{2})';
+ $zone = '([A-Z]{1,5})';
+ $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
+ }
+ if (preg_match($pcre, $date, $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Day name
+ 2: Day
+ 3: Month
+ 4: Year
+ 5: Hour
+ 6: Minute
+ 7: Second
+ 8: Timezone
+ */
+
+ // Month
+ $month = $this->month[strtolower($match[3])];
+
+ // Character timezone
+ if (isset($this->timezone[strtoupper($match[8])]))
+ {
+ $timezone = $this->timezone[strtoupper($match[8])];
+ }
+ // Assume everything else to be -0000
+ else
+ {
+ $timezone = 0;
+ }
+
+ // Deal with 2 digit year
+ if ($match[4] < 50)
+ {
+ $match[4] += 2000;
+ }
+ else
+ {
+ $match[4] += 1900;
+ }
+
+ return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Parse C99's asctime()'s date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_asctime($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $space = '[\x09\x20]+';
+ $wday_name = $this->day_pcre;
+ $mon_name = $this->month_pcre;
+ $day = '([0-9]{1,2})';
+ $hour = $sec = $min = '([0-9]{2})';
+ $year = '([0-9]{4})';
+ $terminator = '\x0A?\x00?';
+ $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
+ }
+ if (preg_match($pcre, $date, $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Day name
+ 2: Month
+ 3: Day
+ 4: Hour
+ 5: Minute
+ 6: Second
+ 7: Year
+ */
+
+ $month = $this->month[strtolower($match[2])];
+ return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Parse dates using strtotime()
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_strtotime($date)
+ {
+ $strtotime = strtotime($date);
+ if ($strtotime === -1 || $strtotime === false)
+ {
+ return false;
+ }
+ else
+ {
+ return $strtotime;
+ }
+ }
+}
+
+/**
+ * Content-type sniffing
+ *
+ * @package SimplePie
+ */
+class SimplePie_Content_Type_Sniffer
+{
+ /**
+ * File object
+ *
+ * @var SimplePie_File
+ * @access private
+ */
+ var $file;
+
+ /**
+ * Create an instance of the class with the input file
+ *
+ * @access public
+ * @param SimplePie_Content_Type_Sniffer $file Input file
+ */
+ function SimplePie_Content_Type_Sniffer($file)
+ {
+ $this->file = $file;
+ }
+
+ /**
+ * Get the Content-Type of the specified file
+ *
+ * @access public
+ * @return string Actual Content-Type
+ */
+ function get_type()
+ {
+ if (isset($this->file->headers['content-type']))
+ {
+ if (!isset($this->file->headers['content-encoding'])
+ && ($this->file->headers['content-type'] === 'text/plain'
+ || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
+ || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
+ {
+ return $this->text_or_binary();
+ }
+
+ if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
+ {
+ $official = substr($this->file->headers['content-type'], 0, $pos);
+ }
+ else
+ {
+ $official = $this->file->headers['content-type'];
+ }
+ $official = strtolower($official);
+
+ if ($official === 'unknown/unknown'
+ || $official === 'application/unknown')
+ {
+ return $this->unknown();
+ }
+ elseif (substr($official, -4) === '+xml'
+ || $official === 'text/xml'
+ || $official === 'application/xml')
+ {
+ return $official;
+ }
+ elseif (substr($official, 0, 6) === 'image/')
+ {
+ if ($return = $this->image())
+ {
+ return $return;
+ }
+ else
+ {
+ return $official;
+ }
+ }
+ elseif ($official === 'text/html')
+ {
+ return $this->feed_or_html();
+ }
+ else
+ {
+ return $official;
+ }
+ }
+ else
+ {
+ return $this->unknown();
+ }
+ }
+
+ /**
+ * Sniff text or binary
+ *
+ * @access private
+ * @return string Actual Content-Type
+ */
+ function text_or_binary()
+ {
+ if (substr($this->file->body, 0, 2) === "\xFE\xFF"
+ || substr($this->file->body, 0, 2) === "\xFF\xFE"
+ || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
+ || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
+ {
+ return 'text/plain';
+ }
+ elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
+ {
+ return 'application/octect-stream';
+ }
+ else
+ {
+ return 'text/plain';
+ }
+ }
+
+ /**
+ * Sniff unknown
+ *
+ * @access private
+ * @return string Actual Content-Type
+ */
+ function unknown()
+ {
+ $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
+ if (strtolower(substr($this->file->body, $ws, 14)) === 'file->body, $ws, 5)) === 'file->body, $ws, 7)) === '';
+ $javascript_outputted = true;
+ }
+ }
+
+ // Odeo Feed MP3's
+ if ($handler == 'odeo')
+ {
+ if ($native)
+ {
+ $embed .= '';
+ }
+ else
+ {
+ $embed .= '';
+ }
+ }
+
+ // Flash
+ elseif ($handler == 'flash')
+ {
+ if ($native)
+ {
+ $embed .= "";
+ }
+ else
+ {
+ $embed .= "";
+ }
+ }
+
+ // Flash Media Player file types.
+ // Preferred handler for MP3 file types.
+ elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
+ {
+ $height += 20;
+ if ($native)
+ {
+ $embed .= "";
+ }
+ else
+ {
+ $embed .= "";
+ }
+ }
+
+ // QuickTime 7 file types. Need to test with QuickTime 6.
+ // Only handle MP3's if the Flash Media Player is not present.
+ elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
+ {
+ $height += 16;
+ if ($native)
+ {
+ if ($placeholder != ""){
+ $embed .= "";
+ }
+ else {
+ $embed .= "";
+ }
+ }
+ else
+ {
+ $embed .= "";
+ }
+ }
+
+ // Windows Media
+ elseif ($handler == 'wmedia')
+ {
+ $height += 45;
+ if ($native)
+ {
+ $embed .= "";
+ }
+ else
+ {
+ $embed .= "";
+ }
+ }
+
+ // Everything else
+ else $embed .= '' . $alt . '';
+
+ return $embed;
+ }
+
+ function get_real_type($find_handler = false)
+ {
+ // If it's Odeo, let's get it out of the way.
+ if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
+ {
+ return 'odeo';
+ }
+
+ // Mime-types by handler.
+ $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
+ $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
+ $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime
+ $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media
+ $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
+
+ if ($this->get_type() !== null)
+ {
+ $type = strtolower($this->type);
+ }
+ else
+ {
+ $type = null;
+ }
+
+ // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
+ if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
+ {
+ switch (strtolower($this->get_extension()))
+ {
+ // Audio mime-types
+ case 'aac':
+ case 'adts':
+ $type = 'audio/acc';
+ break;
+
+ case 'aif':
+ case 'aifc':
+ case 'aiff':
+ case 'cdda':
+ $type = 'audio/aiff';
+ break;
+
+ case 'bwf':
+ $type = 'audio/wav';
+ break;
+
+ case 'kar':
+ case 'mid':
+ case 'midi':
+ case 'smf':
+ $type = 'audio/midi';
+ break;
+
+ case 'm4a':
+ $type = 'audio/x-m4a';
+ break;
+
+ case 'mp3':
+ case 'swa':
+ $type = 'audio/mp3';
+ break;
+
+ case 'wav':
+ $type = 'audio/wav';
+ break;
+
+ case 'wax':
+ $type = 'audio/x-ms-wax';
+ break;
+
+ case 'wma':
+ $type = 'audio/x-ms-wma';
+ break;
+
+ // Video mime-types
+ case '3gp':
+ case '3gpp':
+ $type = 'video/3gpp';
+ break;
+
+ case '3g2':
+ case '3gp2':
+ $type = 'video/3gpp2';
+ break;
+
+ case 'asf':
+ $type = 'video/x-ms-asf';
+ break;
+
+ case 'flv':
+ $type = 'video/x-flv';
+ break;
+
+ case 'm1a':
+ case 'm1s':
+ case 'm1v':
+ case 'm15':
+ case 'm75':
+ case 'mp2':
+ case 'mpa':
+ case 'mpeg':
+ case 'mpg':
+ case 'mpm':
+ case 'mpv':
+ $type = 'video/mpeg';
+ break;
+
+ case 'm4v':
+ $type = 'video/x-m4v';
+ break;
+
+ case 'mov':
+ case 'qt':
+ $type = 'video/quicktime';
+ break;
+
+ case 'mp4':
+ case 'mpg4':
+ $type = 'video/mp4';
+ break;
+
+ case 'sdv':
+ $type = 'video/sd-video';
+ break;
+
+ case 'wm':
+ $type = 'video/x-ms-wm';
+ break;
+
+ case 'wmv':
+ $type = 'video/x-ms-wmv';
+ break;
+
+ case 'wvx':
+ $type = 'video/x-ms-wvx';
+ break;
+
+ // Flash mime-types
+ case 'spl':
+ $type = 'application/futuresplash';
+ break;
+
+ case 'swf':
+ $type = 'application/x-shockwave-flash';
+ break;
+ }
+ }
+
+ if ($find_handler)
+ {
+ if (in_array($type, $types_flash))
+ {
+ return 'flash';
+ }
+ elseif (in_array($type, $types_fmedia))
+ {
+ return 'fmedia';
+ }
+ elseif (in_array($type, $types_quicktime))
+ {
+ return 'quicktime';
+ }
+ elseif (in_array($type, $types_wmedia))
+ {
+ return 'wmedia';
+ }
+ elseif (in_array($type, $types_mp3))
+ {
+ return 'mp3';
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else
+ {
+ return $type;
+ }
+ }
+}
+
+class SimplePie_Caption
+{
+ var $type;
+ var $lang;
+ var $startTime;
+ var $endTime;
+ var $text;
+
+ // Constructor, used to input the data
+ function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
+ {
+ $this->type = $type;
+ $this->lang = $lang;
+ $this->startTime = $startTime;
+ $this->endTime = $endTime;
+ $this->text = $text;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_endtime()
+ {
+ if ($this->endTime !== null)
+ {
+ return $this->endTime;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_language()
+ {
+ if ($this->lang !== null)
+ {
+ return $this->lang;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_starttime()
+ {
+ if ($this->startTime !== null)
+ {
+ return $this->startTime;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_text()
+ {
+ if ($this->text !== null)
+ {
+ return $this->text;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Credit
+{
+ var $role;
+ var $scheme;
+ var $name;
+
+ // Constructor, used to input the data
+ function SimplePie_Credit($role = null, $scheme = null, $name = null)
+ {
+ $this->role = $role;
+ $this->scheme = $scheme;
+ $this->name = $name;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_role()
+ {
+ if ($this->role !== null)
+ {
+ return $this->role;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_scheme()
+ {
+ if ($this->scheme !== null)
+ {
+ return $this->scheme;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_name()
+ {
+ if ($this->name !== null)
+ {
+ return $this->name;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Copyright
+{
+ var $url;
+ var $label;
+
+ // Constructor, used to input the data
+ function SimplePie_Copyright($url = null, $label = null)
+ {
+ $this->url = $url;
+ $this->label = $label;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_url()
+ {
+ if ($this->url !== null)
+ {
+ return $this->url;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_attribution()
+ {
+ if ($this->label !== null)
+ {
+ return $this->label;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Rating
+{
+ var $scheme;
+ var $value;
+
+ // Constructor, used to input the data
+ function SimplePie_Rating($scheme = null, $value = null)
+ {
+ $this->scheme = $scheme;
+ $this->value = $value;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_scheme()
+ {
+ if ($this->scheme !== null)
+ {
+ return $this->scheme;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_value()
+ {
+ if ($this->value !== null)
+ {
+ return $this->value;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Restriction
+{
+ var $relationship;
+ var $type;
+ var $value;
+
+ // Constructor, used to input the data
+ function SimplePie_Restriction($relationship = null, $type = null, $value = null)
+ {
+ $this->relationship = $relationship;
+ $this->type = $type;
+ $this->value = $value;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_relationship()
+ {
+ if ($this->relationship !== null)
+ {
+ return $this->relationship;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_value()
+ {
+ if ($this->value !== null)
+ {
+ return $this->value;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+/**
+ * @todo Move to properly supporting RFC2616 (HTTP/1.1)
+ */
+class SimplePie_File
+{
+ var $url;
+ var $useragent;
+ var $success = true;
+ var $headers = array();
+ var $body;
+ var $status_code;
+ var $redirects = 0;
+ var $error;
+ var $method = SIMPLEPIE_FILE_SOURCE_NONE;
+
+ function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
+ {
+ if (class_exists('idna_convert'))
+ {
+ $idn =& new idna_convert;
+ $parsed = SimplePie_Misc::parse_url($url);
+ $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
+ }
+ $this->url = $url;
+ $this->useragent = $useragent;
+ if (preg_match('/^http(s)?:\/\//i', $url))
+ {
+ if ($useragent === null)
+ {
+ $useragent = ini_get('user_agent');
+ $this->useragent = $useragent;
+ }
+ if (!is_array($headers))
+ {
+ $headers = array();
+ }
+ if (!$force_fsockopen && function_exists('curl_exec'))
+ {
+ $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
+ $fp = curl_init();
+ $headers2 = array();
+ foreach ($headers as $key => $value)
+ {
+ $headers2[] = "$key: $value";
+ }
+ if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
+ {
+ curl_setopt($fp, CURLOPT_ENCODING, '');
+ }
+ curl_setopt($fp, CURLOPT_URL, $url);
+ curl_setopt($fp, CURLOPT_HEADER, 1);
+ curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
+ curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
+ curl_setopt($fp, CURLOPT_REFERER, $url);
+ curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
+ curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
+ if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
+ {
+ curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
+ curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
+ }
+
+ $this->headers = curl_exec($fp);
+ if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
+ {
+ curl_setopt($fp, CURLOPT_ENCODING, 'none');
+ $this->headers = curl_exec($fp);
+ }
+ if (curl_errno($fp))
+ {
+ $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
+ $this->success = false;
+ }
+ else
+ {
+ $info = curl_getinfo($fp);
+ curl_close($fp);
+ $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
+ $this->headers = array_pop($this->headers);
+ $parser =& new SimplePie_HTTP_Parser($this->headers);
+ if ($parser->parse())
+ {
+ $this->headers = $parser->headers;
+ $this->body = $parser->body;
+ $this->status_code = $parser->status_code;
+ if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
+ {
+ $this->redirects++;
+ $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
+ return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
+ }
+ }
+ }
+ }
+ else
+ {
+ $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
+ $url_parts = parse_url($url);
+ if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
+ {
+ $url_parts['host'] = "ssl://$url_parts[host]";
+ $url_parts['port'] = 443;
+ }
+ if (!isset($url_parts['port']))
+ {
+ $url_parts['port'] = 80;
+ }
+ $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
+ if (!$fp)
+ {
+ $this->error = 'fsockopen error: ' . $errstr;
+ $this->success = false;
+ }
+ else
+ {
+ stream_set_timeout($fp, $timeout);
+ if (isset($url_parts['path']))
+ {
+ if (isset($url_parts['query']))
+ {
+ $get = "$url_parts[path]?$url_parts[query]";
+ }
+ else
+ {
+ $get = $url_parts['path'];
+ }
+ }
+ else
+ {
+ $get = '/';
+ }
+ $out = "GET $get HTTP/1.0\r\n";
+ $out .= "Host: $url_parts[host]\r\n";
+ $out .= "User-Agent: $useragent\r\n";
+ if (function_exists('gzinflate'))
+ {
+ $out .= "Accept-Encoding: gzip,deflate\r\n";
+ }
+
+ if (isset($url_parts['user']) && isset($url_parts['pass']))
+ {
+ $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
+ }
+ foreach ($headers as $key => $value)
+ {
+ $out .= "$key: $value\r\n";
+ }
+ $out .= "Connection: Close\r\n\r\n";
+ fwrite($fp, $out);
+
+ $info = stream_get_meta_data($fp);
+
+ $this->headers = '';
+ while (!$info['eof'] && !$info['timed_out'])
+ {
+ $this->headers .= fread($fp, 1160);
+ $info = stream_get_meta_data($fp);
+ }
+ if (!$info['timed_out'])
+ {
+ $parser =& new SimplePie_HTTP_Parser($this->headers);
+ if ($parser->parse())
+ {
+ $this->headers = $parser->headers;
+ $this->body = $parser->body;
+ $this->status_code = $parser->status_code;
+ if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
+ {
+ $this->redirects++;
+ $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
+ return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
+ }
+ if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
+ {
+ if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
+ {
+ $this->body = substr($this->body, 10);
+ }
+ $this->body = gzinflate($this->body);
+ }
+ }
+ }
+ else
+ {
+ $this->error = 'fsocket timed out';
+ $this->success = false;
+ }
+ fclose($fp);
+ }
+ }
+ }
+ else
+ {
+ $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
+ if (!$this->body = file_get_contents($url))
+ {
+ $this->error = 'file_get_contents could not read the file';
+ $this->success = false;
+ }
+ }
+ }
+}
+
+/**
+ * HTTP Response Parser
+ *
+ * @package SimplePie
+ */
+class SimplePie_HTTP_Parser
+{
+ /**
+ * HTTP Version
+ *
+ * @access public
+ * @var float
+ */
+ var $http_version = 0.0;
+
+ /**
+ * Status code
+ *
+ * @access public
+ * @var int
+ */
+ var $status_code = 0;
+
+ /**
+ * Reason phrase
+ *
+ * @access public
+ * @var string
+ */
+ var $reason = '';
+
+ /**
+ * Key/value pairs of the headers
+ *
+ * @access public
+ * @var array
+ */
+ var $headers = array();
+
+ /**
+ * Body of the response
+ *
+ * @access public
+ * @var string
+ */
+ var $body = '';
+
+ /**
+ * Current state of the state machine
+ *
+ * @access private
+ * @var string
+ */
+ var $state = 'http_version';
+
+ /**
+ * Input data
+ *
+ * @access private
+ * @var string
+ */
+ var $data = '';
+
+ /**
+ * Input data length (to avoid calling strlen() everytime this is needed)
+ *
+ * @access private
+ * @var int
+ */
+ var $data_length = 0;
+
+ /**
+ * Current position of the pointer
+ *
+ * @var int
+ * @access private
+ */
+ var $position = 0;
+
+ /**
+ * Name of the hedaer currently being parsed
+ *
+ * @access private
+ * @var string
+ */
+ var $name = '';
+
+ /**
+ * Value of the hedaer currently being parsed
+ *
+ * @access private
+ * @var string
+ */
+ var $value = '';
+
+ /**
+ * Create an instance of the class with the input data
+ *
+ * @access public
+ * @param string $data Input data
+ */
+ function SimplePie_HTTP_Parser($data)
+ {
+ $this->data = $data;
+ $this->data_length = strlen($this->data);
+ }
+
+ /**
+ * Parse the input data
+ *
+ * @access public
+ * @return bool true on success, false on failure
+ */
+ function parse()
+ {
+ while ($this->state && $this->state !== 'emit' && $this->has_data())
+ {
+ $state = $this->state;
+ $this->$state();
+ }
+ $this->data = '';
+ if ($this->state === 'emit')
+ {
+ return true;
+ }
+ else
+ {
+ $this->http_version = '';
+ $this->status_code = '';
+ $this->reason = '';
+ $this->headers = array();
+ $this->body = '';
+ return false;
+ }
+ }
+
+ /**
+ * Check whether there is data beyond the pointer
+ *
+ * @access private
+ * @return bool true if there is further data, false if not
+ */
+ function has_data()
+ {
+ return (bool) ($this->position < $this->data_length);
+ }
+
+ /**
+ * See if the next character is LWS
+ *
+ * @access private
+ * @return bool true if the next character is LWS, false if not
+ */
+ function is_linear_whitespace()
+ {
+ return (bool) ($this->data[$this->position] === "\x09"
+ || $this->data[$this->position] === "\x20"
+ || ($this->data[$this->position] === "\x0A"
+ && isset($this->data[$this->position + 1])
+ && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
+ }
+
+ /**
+ * Parse the HTTP version
+ *
+ * @access private
+ */
+ function http_version()
+ {
+ if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
+ {
+ $len = strspn($this->data, '0123456789.', 5);
+ $this->http_version = substr($this->data, 5, $len);
+ $this->position += 5 + $len;
+ if (substr_count($this->http_version, '.') <= 1)
+ {
+ $this->http_version = (float) $this->http_version;
+ $this->position += strspn($this->data, "\x09\x20", $this->position);
+ $this->state = 'status';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ /**
+ * Parse the status code
+ *
+ * @access private
+ */
+ function status()
+ {
+ if ($len = strspn($this->data, '0123456789', $this->position))
+ {
+ $this->status_code = (int) substr($this->data, $this->position, $len);
+ $this->position += $len;
+ $this->state = 'reason';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ /**
+ * Parse the reason phrase
+ *
+ * @access private
+ */
+ function reason()
+ {
+ $len = strcspn($this->data, "\x0A", $this->position);
+ $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
+ $this->position += $len + 1;
+ $this->state = 'new_line';
+ }
+
+ /**
+ * Deal with a new line, shifting data around as needed
+ *
+ * @access private
+ */
+ function new_line()
+ {
+ $this->value = trim($this->value, "\x0D\x20");
+ if ($this->name !== '' && $this->value !== '')
+ {
+ $this->name = strtolower($this->name);
+ if (isset($this->headers[$this->name]))
+ {
+ $this->headers[$this->name] .= ', ' . $this->value;
+ }
+ else
+ {
+ $this->headers[$this->name] = $this->value;
+ }
+ }
+ $this->name = '';
+ $this->value = '';
+ if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
+ {
+ $this->position += 2;
+ $this->state = 'body';
+ }
+ elseif ($this->data[$this->position] === "\x0A")
+ {
+ $this->position++;
+ $this->state = 'body';
+ }
+ else
+ {
+ $this->state = 'name';
+ }
+ }
+
+ /**
+ * Parse a header name
+ *
+ * @access private
+ */
+ function name()
+ {
+ $len = strcspn($this->data, "\x0A:", $this->position);
+ if (isset($this->data[$this->position + $len]))
+ {
+ if ($this->data[$this->position + $len] === "\x0A")
+ {
+ $this->position += $len;
+ $this->state = 'new_line';
+ }
+ else
+ {
+ $this->name = substr($this->data, $this->position, $len);
+ $this->position += $len + 1;
+ $this->state = 'value';
+ }
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ /**
+ * Parse LWS, replacing consecutive LWS characters with a single space
+ *
+ * @access private
+ */
+ function linear_whitespace()
+ {
+ do
+ {
+ if (substr($this->data, $this->position, 2) === "\x0D\x0A")
+ {
+ $this->position += 2;
+ }
+ elseif ($this->data[$this->position] === "\x0A")
+ {
+ $this->position++;
+ }
+ $this->position += strspn($this->data, "\x09\x20", $this->position);
+ } while ($this->has_data() && $this->is_linear_whitespace());
+ $this->value .= "\x20";
+ }
+
+ /**
+ * See what state to move to while within non-quoted header values
+ *
+ * @access private
+ */
+ function value()
+ {
+ if ($this->is_linear_whitespace())
+ {
+ $this->linear_whitespace();
+ }
+ else
+ {
+ switch ($this->data[$this->position])
+ {
+ case '"':
+ $this->position++;
+ $this->state = 'quote';
+ break;
+
+ case "\x0A":
+ $this->position++;
+ $this->state = 'new_line';
+ break;
+
+ default:
+ $this->state = 'value_char';
+ break;
+ }
+ }
+ }
+
+ /**
+ * Parse a header value while outside quotes
+ *
+ * @access private
+ */
+ function value_char()
+ {
+ $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
+ $this->value .= substr($this->data, $this->position, $len);
+ $this->position += $len;
+ $this->state = 'value';
+ }
+
+ /**
+ * See what state to move to while within quoted header values
+ *
+ * @access private
+ */
+ function quote()
+ {
+ if ($this->is_linear_whitespace())
+ {
+ $this->linear_whitespace();
+ }
+ else
+ {
+ switch ($this->data[$this->position])
+ {
+ case '"':
+ $this->position++;
+ $this->state = 'value';
+ break;
+
+ case "\x0A":
+ $this->position++;
+ $this->state = 'new_line';
+ break;
+
+ case '\\':
+ $this->position++;
+ $this->state = 'quote_escaped';
+ break;
+
+ default:
+ $this->state = 'quote_char';
+ break;
+ }
+ }
+ }
+
+ /**
+ * Parse a header value while within quotes
+ *
+ * @access private
+ */
+ function quote_char()
+ {
+ $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
+ $this->value .= substr($this->data, $this->position, $len);
+ $this->position += $len;
+ $this->state = 'value';
+ }
+
+ /**
+ * Parse an escaped character within quotes
+ *
+ * @access private
+ */
+ function quote_escaped()
+ {
+ $this->value .= $this->data[$this->position];
+ $this->position++;
+ $this->state = 'quote';
+ }
+
+ /**
+ * Parse the body
+ *
+ * @access private
+ */
+ function body()
+ {
+ $this->body = substr($this->data, $this->position);
+ $this->state = 'emit';
+ }
+}
+
+class SimplePie_Cache
+{
+ /**
+ * Don't call the constructor. Please.
+ *
+ * @access private
+ */
+ function SimplePie_Cache()
+ {
+ trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
+ }
+
+ /**
+ * Create a new SimplePie_Cache object
+ *
+ * @static
+ * @access public
+ */
+ function create($location, $filename, $extension)
+ {
+ return new SimplePie_Cache_File($location, $filename, $extension);
+ }
+}
+
+class SimplePie_Cache_File
+{
+ var $location;
+ var $filename;
+ var $extension;
+ var $name;
+
+ function SimplePie_Cache_File($location, $filename, $extension)
+ {
+ $this->location = $location;
+ $this->filename = rawurlencode($filename);
+ $this->extension = rawurlencode($extension);
+ $this->name = "$location/$this->filename.$this->extension";
+ }
+
+ function save($data)
+ {
+ if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
+ {
+ if (is_a($data, 'SimplePie'))
+ {
+ $data = $data->data;
+ }
+
+ $data = serialize($data);
+
+ if (function_exists('file_put_contents'))
+ {
+ return (bool) file_put_contents($this->name, $data);
+ }
+ else
+ {
+ $fp = fopen($this->name, 'wb');
+ if ($fp)
+ {
+ fwrite($fp, $data);
+ fclose($fp);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ function load()
+ {
+ if (file_exists($this->name) && is_readable($this->name))
+ {
+ return unserialize(file_get_contents($this->name));
+ }
+ return false;
+ }
+
+ function mtime()
+ {
+ if (file_exists($this->name))
+ {
+ return filemtime($this->name);
+ }
+ return false;
+ }
+
+ function touch()
+ {
+ if (file_exists($this->name))
+ {
+ return touch($this->name);
+ }
+ return false;
+ }
+
+ function unlink()
+ {
+ if (file_exists($this->name))
+ {
+ return unlink($this->name);
+ }
+ return false;
+ }
+}
+
+class SimplePie_Misc
+{
+ function time_hms($seconds)
+ {
+ $time = '';
+
+ $hours = floor($seconds / 3600);
+ $remainder = $seconds % 3600;
+ if ($hours > 0)
+ {
+ $time .= $hours.':';
+ }
+
+ $minutes = floor($remainder / 60);
+ $seconds = $remainder % 60;
+ if ($minutes < 10 && $hours > 0)
+ {
+ $minutes = '0' . $minutes;
+ }
+ if ($seconds < 10)
+ {
+ $seconds = '0' . $seconds;
+ }
+
+ $time .= $minutes.':';
+ $time .= $seconds;
+
+ return $time;
+ }
+
+ function absolutize_url($relative, $base)
+ {
+ if ($relative !== '')
+ {
+ $relative = SimplePie_Misc::parse_url($relative);
+ if ($relative['scheme'] !== '')
+ {
+ $target = $relative;
+ }
+ elseif ($base !== '')
+ {
+ $base = SimplePie_Misc::parse_url($base);
+ $target = SimplePie_Misc::parse_url('');
+ if ($relative['authority'] !== '')
+ {
+ $target = $relative;
+ $target['scheme'] = $base['scheme'];
+ }
+ else
+ {
+ $target['scheme'] = $base['scheme'];
+ $target['authority'] = $base['authority'];
+ if ($relative['path'] !== '')
+ {
+ if (strpos($relative['path'], '/') === 0)
+ {
+ $target['path'] = $relative['path'];
+ }
+ elseif ($base['authority'] !== '' && $base['path'] === '')
+ {
+ $target['path'] = '/' . $relative['path'];
+ }
+ elseif (($last_segment = strrpos($base['path'], '/')) !== false)
+ {
+ $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
+ }
+ else
+ {
+ $target['path'] = $relative['path'];
+ }
+ $target['query'] = $relative['query'];
+ }
+ else
+ {
+ $target['path'] = $base['path'];
+ if ($relative['query'] !== '')
+ {
+ $target['query'] = $relative['query'];
+ }
+ elseif ($base['query'] !== '')
+ {
+ $target['query'] = $base['query'];
+ }
+ }
+ }
+ $target['fragment'] = $relative['fragment'];
+ }
+ else
+ {
+ // No base URL, just return the relative URL
+ $target = $relative;
+ }
+ $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
+ }
+ else
+ {
+ $return = $base;
+ }
+ $return = SimplePie_Misc::normalize_url($return);
+ return $return;
+ }
+
+ function remove_dot_segments($input)
+ {
+ $output = '';
+ while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
+ {
+ // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
+ if (strpos($input, '../') === 0)
+ {
+ $input = substr($input, 3);
+ }
+ elseif (strpos($input, './') === 0)
+ {
+ $input = substr($input, 2);
+ }
+ // 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,
+ elseif (strpos($input, '/./') === 0)
+ {
+ $input = substr_replace($input, '/', 0, 3);
+ }
+ elseif ($input == '/.')
+ {
+ $input = '/';
+ }
+ // 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,
+ elseif (strpos($input, '/../') === 0)
+ {
+ $input = substr_replace($input, '/', 0, 4);
+ $output = substr_replace($output, '', strrpos($output, '/'));
+ }
+ elseif ($input == '/..')
+ {
+ $input = '/';
+ $output = substr_replace($output, '', strrpos($output, '/'));
+ }
+ // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
+ elseif ($input == '.' || $input == '..')
+ {
+ $input = '';
+ }
+ // 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
+ elseif (($pos = strpos($input, '/', 1)) !== false)
+ {
+ $output .= substr($input, 0, $pos);
+ $input = substr_replace($input, '', 0, $pos);
+ }
+ else
+ {
+ $output .= $input;
+ $input = '';
+ }
+ }
+ return $output . $input;
+ }
+
+ function get_element($realname, $string)
+ {
+ $return = array();
+ $name = preg_quote($realname, '/');
+ if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
+ {
+ for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
+ {
+ $return[$i]['tag'] = $realname;
+ $return[$i]['full'] = $matches[$i][0][0];
+ $return[$i]['offset'] = $matches[$i][0][1];
+ if (strlen($matches[$i][3][0]) <= 2)
+ {
+ $return[$i]['self_closing'] = true;
+ }
+ else
+ {
+ $return[$i]['self_closing'] = false;
+ $return[$i]['content'] = $matches[$i][4][0];
+ }
+ $return[$i]['attribs'] = array();
+ if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
+ {
+ for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
+ {
+ if (count($attribs[$j]) == 2)
+ {
+ $attribs[$j][2] = $attribs[$j][1];
+ }
+ $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
+ }
+ }
+ }
+ }
+ return $return;
+ }
+
+ function element_implode($element)
+ {
+ $full = "<$element[tag]";
+ foreach ($element['attribs'] as $key => $value)
+ {
+ $key = strtolower($key);
+ $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
+ }
+ if ($element['self_closing'])
+ {
+ $full .= ' />';
+ }
+ else
+ {
+ $full .= ">$element[content]$element[tag]>";
+ }
+ return $full;
+ }
+
+ function error($message, $level, $file, $line)
+ {
+ switch ($level)
+ {
+ case E_USER_ERROR:
+ $note = 'PHP Error';
+ break;
+ case E_USER_WARNING:
+ $note = 'PHP Warning';
+ break;
+ case E_USER_NOTICE:
+ $note = 'PHP Notice';
+ break;
+ default:
+ $note = 'Unknown Error';
+ break;
+ }
+ error_log("$note: $message in $file on line $line", 0);
+ return $message;
+ }
+
+ /**
+ * If a file has been cached, retrieve and display it.
+ *
+ * This is most useful for caching images (get_favicon(), etc.),
+ * however it works for all cached files. This WILL NOT display ANY
+ * file/image/page/whatever, but rather only display what has already
+ * been cached by SimplePie.
+ *
+ * @access public
+ * @see SimplePie::get_favicon()
+ * @param str $identifier_url URL that is used to identify the content.
+ * This may or may not be the actual URL of the live content.
+ * @param str $cache_location Location of SimplePie's cache. Defaults
+ * to './cache'.
+ * @param str $cache_extension The file extension that the file was
+ * cached with. Defaults to 'spc'.
+ * @param str $cache_class Name of the cache-handling class being used
+ * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
+ * as-is unless you've overloaded the class.
+ * @param str $cache_name_function Obsolete. Exists for backwards
+ * compatibility reasons only.
+ */
+ function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
+ {
+ $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
+
+ if ($file = $cache->load())
+ {
+ if (isset($file['headers']['content-type']))
+ {
+ header('Content-type:' . $file['headers']['content-type']);
+ }
+ else
+ {
+ header('Content-type: application/octet-stream');
+ }
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
+ echo $file['body'];
+ exit;
+ }
+
+ die('Cached file for ' . $identifier_url . ' cannot be found.');
+ }
+
+ function fix_protocol($url, $http = 1)
+ {
+ $url = SimplePie_Misc::normalize_url($url);
+ $parsed = SimplePie_Misc::parse_url($url);
+ if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
+ {
+ return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
+ }
+
+ if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
+ {
+ return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
+ }
+
+ if ($http == 2 && $parsed['scheme'] !== '')
+ {
+ return "feed:$url";
+ }
+ elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
+ {
+ return substr_replace($url, 'podcast', 0, 4);
+ }
+ elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
+ {
+ return substr_replace($url, 'itpc', 0, 4);
+ }
+ else
+ {
+ return $url;
+ }
+ }
+
+ function parse_url($url)
+ {
+ static $cache = array();
+ if (isset($cache[$url]))
+ {
+ return $cache[$url];
+ }
+ elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
+ {
+ for ($i = count($match); $i <= 9; $i++)
+ {
+ $match[$i] = '';
+ }
+ return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
+ }
+ else
+ {
+ return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
+ }
+ }
+
+ function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
+ {
+ $return = '';
+ if ($scheme !== '')
+ {
+ $return .= "$scheme:";
+ }
+ if ($authority !== '')
+ {
+ $return .= "//$authority";
+ }
+ if ($path !== '')
+ {
+ $return .= $path;
+ }
+ if ($query !== '')
+ {
+ $return .= "?$query";
+ }
+ if ($fragment !== '')
+ {
+ $return .= "#$fragment";
+ }
+ return $return;
+ }
+
+ function normalize_url($url)
+ {
+ $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
+ $url = SimplePie_Misc::parse_url($url);
+ $url['scheme'] = strtolower($url['scheme']);
+ if ($url['authority'] !== '')
+ {
+ $url['authority'] = strtolower($url['authority']);
+ $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
+ }
+ return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
+ }
+
+ function percent_encoding_normalization($match)
+ {
+ $integer = hexdec($match[1]);
+ if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
+ {
+ return chr($integer);
+ }
+ else
+ {
+ return strtoupper($match[0]);
+ }
+ }
+
+ /**
+ * Remove bad UTF-8 bytes
+ *
+ * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
+ * FAQ: Multilingual Forms (modified to include full ASCII range)
+ *
+ * @author Geoffrey Sneddon
+ * @see http://www.w3.org/International/questions/qa-forms-utf-8
+ * @param string $str String to remove bad UTF-8 bytes from
+ * @return string UTF-8 string
+ */
+ function utf8_bad_replace($str)
+ {
+ if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
+ {
+ return $return;
+ }
+ elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
+ {
+ return $return;
+ }
+ elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches))
+ {
+ return implode("\xEF\xBF\xBD", $matches[0]);
+ }
+ elseif ($str !== '')
+ {
+ return "\xEF\xBF\xBD";
+ }
+ else
+ {
+ return '';
+ }
+ }
+
+ /**
+ * Converts a Windows-1252 encoded string to a UTF-8 encoded string
+ *
+ * @static
+ * @access public
+ * @param string $string Windows-1252 encoded string
+ * @return string UTF-8 encoded string
+ */
+ function windows_1252_to_utf8($string)
+ {
+ static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
+
+ return strtr($string, $convert_table);
+ }
+
+ function change_encoding($data, $input, $output)
+ {
+ $input = SimplePie_Misc::encoding($input);
+ $output = SimplePie_Misc::encoding($output);
+
+ // We fail to fail on non US-ASCII bytes
+ if ($input === 'US-ASCII')
+ {
+ static $non_ascii_octects = '';
+ if (!$non_ascii_octects)
+ {
+ for ($i = 0x80; $i <= 0xFF; $i++)
+ {
+ $non_ascii_octects .= chr($i);
+ }
+ }
+ $data = substr($data, 0, strcspn($data, $non_ascii_octects));
+ }
+
+ if (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
+ {
+ return $return;
+ }
+ elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
+ {
+ return $return;
+ }
+ elseif ($input == 'windows-1252' && $output == 'UTF-8')
+ {
+ return SimplePie_Misc::windows_1252_to_utf8($data);
+ }
+ elseif ($input == 'UTF-8' && $output == 'windows-1252')
+ {
+ return utf8_decode($data);
+ }
+ return $data;
+ }
+
+ function encoding($encoding)
+ {
+ // Character sets are case-insensitive (though we'll return them in the form given in their registration)
+ switch (strtoupper($encoding))
+ {
+ case 'ANSI_X3.110-1983':
+ case 'CSA_T500-1983':
+ case 'CSISO99NAPLPS':
+ case 'ISO-IR-99':
+ case 'NAPLPS':
+ return 'ANSI_X3.110-1983';
+
+ case 'ARABIC7':
+ case 'ASMO_449':
+ case 'CSISO89ASMO449':
+ case 'ISO-IR-89':
+ case 'ISO_9036':
+ return 'ASMO_449';
+
+ case 'ADOBE-STANDARD-ENCODING':
+ case 'CSADOBESTANDARDENCODING':
+ return 'Adobe-Standard-Encoding';
+
+ case 'ADOBE-SYMBOL-ENCODING':
+ case 'CSHPPSMATH':
+ return 'Adobe-Symbol-Encoding';
+
+ case 'AMI-1251':
+ case 'AMI1251':
+ case 'AMIGA-1251':
+ case 'AMIGA1251':
+ return 'Amiga-1251';
+
+ case 'BOCU-1':
+ case 'CSBOCU-1':
+ return 'BOCU-1';
+
+ case 'BRF':
+ case 'CSBRF':
+ return 'BRF';
+
+ case 'BS_4730':
+ case 'CSISO4UNITEDKINGDOM':
+ case 'GB':
+ case 'ISO-IR-4':
+ case 'ISO646-GB':
+ case 'UK':
+ return 'BS_4730';
+
+ case 'BS_VIEWDATA':
+ case 'CSISO47BSVIEWDATA':
+ case 'ISO-IR-47':
+ return 'BS_viewdata';
+
+ case 'BIG5':
+ case 'CSBIG5':
+ return 'Big5';
+
+ case 'BIG5-HKSCS':
+ return 'Big5-HKSCS';
+
+ case 'CESU-8':
+ case 'CSCESU-8':
+ return 'CESU-8';
+
+ case 'CA':
+ case 'CSA7-1':
+ case 'CSA_Z243.4-1985-1':
+ case 'CSISO121CANADIAN1':
+ case 'ISO-IR-121':
+ case 'ISO646-CA':
+ return 'CSA_Z243.4-1985-1';
+
+ case 'CSA7-2':
+ case 'CSA_Z243.4-1985-2':
+ case 'CSISO122CANADIAN2':
+ case 'ISO-IR-122':
+ case 'ISO646-CA2':
+ return 'CSA_Z243.4-1985-2';
+
+ case 'CSA_Z243.4-1985-GR':
+ case 'CSISO123CSAZ24341985GR':
+ case 'ISO-IR-123':
+ return 'CSA_Z243.4-1985-gr';
+
+ case 'CSISO139CSN369103':
+ case 'CSN_369103':
+ case 'ISO-IR-139':
+ return 'CSN_369103';
+
+ case 'CSDECMCS':
+ case 'DEC':
+ case 'DEC-MCS':
+ return 'DEC-MCS';
+
+ case 'CSISO21GERMAN':
+ case 'DE':
+ case 'DIN_66003':
+ case 'ISO-IR-21':
+ case 'ISO646-DE':
+ return 'DIN_66003';
+
+ case 'CSISO646DANISH':
+ case 'DK':
+ case 'DS2089':
+ case 'DS_2089':
+ case 'ISO646-DK':
+ return 'DS_2089';
+
+ case 'CSIBMEBCDICATDE':
+ case 'EBCDIC-AT-DE':
+ return 'EBCDIC-AT-DE';
+
+ case 'CSEBCDICATDEA':
+ case 'EBCDIC-AT-DE-A':
+ return 'EBCDIC-AT-DE-A';
+
+ case 'CSEBCDICCAFR':
+ case 'EBCDIC-CA-FR':
+ return 'EBCDIC-CA-FR';
+
+ case 'CSEBCDICDKNO':
+ case 'EBCDIC-DK-NO':
+ return 'EBCDIC-DK-NO';
+
+ case 'CSEBCDICDKNOA':
+ case 'EBCDIC-DK-NO-A':
+ return 'EBCDIC-DK-NO-A';
+
+ case 'CSEBCDICES':
+ case 'EBCDIC-ES':
+ return 'EBCDIC-ES';
+
+ case 'CSEBCDICESA':
+ case 'EBCDIC-ES-A':
+ return 'EBCDIC-ES-A';
+
+ case 'CSEBCDICESS':
+ case 'EBCDIC-ES-S':
+ return 'EBCDIC-ES-S';
+
+ case 'CSEBCDICFISE':
+ case 'EBCDIC-FI-SE':
+ return 'EBCDIC-FI-SE';
+
+ case 'CSEBCDICFISEA':
+ case 'EBCDIC-FI-SE-A':
+ return 'EBCDIC-FI-SE-A';
+
+ case 'CSEBCDICFR':
+ case 'EBCDIC-FR':
+ return 'EBCDIC-FR';
+
+ case 'CSEBCDICIT':
+ case 'EBCDIC-IT':
+ return 'EBCDIC-IT';
+
+ case 'CSEBCDICPT':
+ case 'EBCDIC-PT':
+ return 'EBCDIC-PT';
+
+ case 'CSEBCDICUK':
+ case 'EBCDIC-UK':
+ return 'EBCDIC-UK';
+
+ case 'CSEBCDICUS':
+ case 'EBCDIC-US':
+ return 'EBCDIC-US';
+
+ case 'CSISO111ECMACYRILLIC':
+ case 'ECMA-CYRILLIC':
+ case 'ISO-IR-111':
+ case 'KOI8-E':
+ return 'ECMA-cyrillic';
+
+ case 'CSISO17SPANISH':
+ case 'ES':
+ case 'ISO-IR-17':
+ case 'ISO646-ES':
+ return 'ES';
+
+ case 'CSISO85SPANISH2':
+ case 'ES2':
+ case 'ISO-IR-85':
+ case 'ISO646-ES2':
+ return 'ES2';
+
+ case 'CSEUCPKDFMTJAPANESE':
+ case 'EUC-JP':
+ case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
+ return 'EUC-JP';
+
+ case 'CSEUCKR':
+ case 'EUC-KR':
+ return 'EUC-KR';
+
+ case 'CSEUCFIXWIDJAPANESE':
+ case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
+ return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
+
+ case 'GB18030':
+ return 'GB18030';
+
+ case 'CSGB2312':
+ case 'GB2312':
+ return 'GB2312';
+
+ case 'CP936':
+ case 'GBK':
+ case 'MS936':
+ case 'WINDOWS-936':
+ return 'GBK';
+
+ case 'CN':
+ case 'CSISO57GB1988':
+ case 'GB_1988-80':
+ case 'ISO-IR-57':
+ case 'ISO646-CN':
+ return 'GB_1988-80';
+
+ case 'CHINESE':
+ case 'CSISO58GB231280':
+ case 'GB_2312-80':
+ case 'ISO-IR-58':
+ return 'GB_2312-80';
+
+ case 'CSISO153GOST1976874':
+ case 'GOST_19768-74':
+ case 'ISO-IR-153':
+ case 'ST_SEV_358-88':
+ return 'GOST_19768-74';
+
+ case 'CSHPDESKTOP':
+ case 'HP-DESKTOP':
+ return 'HP-DeskTop';
+
+ case 'CSHPLEGAL':
+ case 'HP-LEGAL':
+ return 'HP-Legal';
+
+ case 'CSHPMATH8':
+ case 'HP-MATH8':
+ return 'HP-Math8';
+
+ case 'CSHPPIFONT':
+ case 'HP-PI-FONT':
+ return 'HP-Pi-font';
+
+ case 'HZ-GB-2312':
+ return 'HZ-GB-2312';
+
+ case 'CSIBMSYMBOLS':
+ case 'IBM-SYMBOLS':
+ return 'IBM-Symbols';
+
+ case 'CSIBMTHAI':
+ case 'IBM-THAI':
+ return 'IBM-Thai';
+
+ case 'CCSID00858':
+ case 'CP00858':
+ case 'IBM00858':
+ case 'PC-MULTILINGUAL-850+EURO':
+ return 'IBM00858';
+
+ case 'CCSID00924':
+ case 'CP00924':
+ case 'EBCDIC-LATIN9--EURO':
+ case 'IBM00924':
+ return 'IBM00924';
+
+ case 'CCSID01140':
+ case 'CP01140':
+ case 'EBCDIC-US-37+EURO':
+ case 'IBM01140':
+ return 'IBM01140';
+
+ case 'CCSID01141':
+ case 'CP01141':
+ case 'EBCDIC-DE-273+EURO':
+ case 'IBM01141':
+ return 'IBM01141';
+
+ case 'CCSID01142':
+ case 'CP01142':
+ case 'EBCDIC-DK-277+EURO':
+ case 'EBCDIC-NO-277+EURO':
+ case 'IBM01142':
+ return 'IBM01142';
+
+ case 'CCSID01143':
+ case 'CP01143':
+ case 'EBCDIC-FI-278+EURO':
+ case 'EBCDIC-SE-278+EURO':
+ case 'IBM01143':
+ return 'IBM01143';
+
+ case 'CCSID01144':
+ case 'CP01144':
+ case 'EBCDIC-IT-280+EURO':
+ case 'IBM01144':
+ return 'IBM01144';
+
+ case 'CCSID01145':
+ case 'CP01145':
+ case 'EBCDIC-ES-284+EURO':
+ case 'IBM01145':
+ return 'IBM01145';
+
+ case 'CCSID01146':
+ case 'CP01146':
+ case 'EBCDIC-GB-285+EURO':
+ case 'IBM01146':
+ return 'IBM01146';
+
+ case 'CCSID01147':
+ case 'CP01147':
+ case 'EBCDIC-FR-297+EURO':
+ case 'IBM01147':
+ return 'IBM01147';
+
+ case 'CCSID01148':
+ case 'CP01148':
+ case 'EBCDIC-INTERNATIONAL-500+EURO':
+ case 'IBM01148':
+ return 'IBM01148';
+
+ case 'CCSID01149':
+ case 'CP01149':
+ case 'EBCDIC-IS-871+EURO':
+ case 'IBM01149':
+ return 'IBM01149';
+
+ case 'CP037':
+ case 'CSIBM037':
+ case 'EBCDIC-CP-CA':
+ case 'EBCDIC-CP-NL':
+ case 'EBCDIC-CP-US':
+ case 'EBCDIC-CP-WT':
+ case 'IBM037':
+ return 'IBM037';
+
+ case 'CP038':
+ case 'CSIBM038':
+ case 'EBCDIC-INT':
+ case 'IBM038':
+ return 'IBM038';
+
+ case 'CP1026':
+ case 'CSIBM1026':
+ case 'IBM1026':
+ return 'IBM1026';
+
+ case 'IBM-1047':
+ case 'IBM1047':
+ return 'IBM1047';
+
+ case 'CP273':
+ case 'CSIBM273':
+ case 'IBM273':
+ return 'IBM273';
+
+ case 'CP274':
+ case 'CSIBM274':
+ case 'EBCDIC-BE':
+ case 'IBM274':
+ return 'IBM274';
+
+ case 'CP275':
+ case 'CSIBM275':
+ case 'EBCDIC-BR':
+ case 'IBM275':
+ return 'IBM275';
+
+ case 'CSIBM277':
+ case 'EBCDIC-CP-DK':
+ case 'EBCDIC-CP-NO':
+ case 'IBM277':
+ return 'IBM277';
+
+ case 'CP278':
+ case 'CSIBM278':
+ case 'EBCDIC-CP-FI':
+ case 'EBCDIC-CP-SE':
+ case 'IBM278':
+ return 'IBM278';
+
+ case 'CP280':
+ case 'CSIBM280':
+ case 'EBCDIC-CP-IT':
+ case 'IBM280':
+ return 'IBM280';
+
+ case 'CP281':
+ case 'CSIBM281':
+ case 'EBCDIC-JP-E':
+ case 'IBM281':
+ return 'IBM281';
+
+ case 'CP284':
+ case 'CSIBM284':
+ case 'EBCDIC-CP-ES':
+ case 'IBM284':
+ return 'IBM284';
+
+ case 'CP285':
+ case 'CSIBM285':
+ case 'EBCDIC-CP-GB':
+ case 'IBM285':
+ return 'IBM285';
+
+ case 'CP290':
+ case 'CSIBM290':
+ case 'EBCDIC-JP-KANA':
+ case 'IBM290':
+ return 'IBM290';
+
+ case 'CP297':
+ case 'CSIBM297':
+ case 'EBCDIC-CP-FR':
+ case 'IBM297':
+ return 'IBM297';
+
+ case 'CP420':
+ case 'CSIBM420':
+ case 'EBCDIC-CP-AR1':
+ case 'IBM420':
+ return 'IBM420';
+
+ case 'CP423':
+ case 'CSIBM423':
+ case 'EBCDIC-CP-GR':
+ case 'IBM423':
+ return 'IBM423';
+
+ case 'CP424':
+ case 'CSIBM424':
+ case 'EBCDIC-CP-HE':
+ case 'IBM424':
+ return 'IBM424';
+
+ case '437':
+ case 'CP437':
+ case 'CSPC8CODEPAGE437':
+ case 'IBM437':
+ return 'IBM437';
+
+ case 'CP500':
+ case 'CSIBM500':
+ case 'EBCDIC-CP-BE':
+ case 'EBCDIC-CP-CH':
+ case 'IBM500':
+ return 'IBM500';
+
+ case 'CP775':
+ case 'CSPC775BALTIC':
+ case 'IBM775':
+ return 'IBM775';
+
+ case '850':
+ case 'CP850':
+ case 'CSPC850MULTILINGUAL':
+ case 'IBM850':
+ return 'IBM850';
+
+ case '851':
+ case 'CP851':
+ case 'CSIBM851':
+ case 'IBM851':
+ return 'IBM851';
+
+ case '852':
+ case 'CP852':
+ case 'CSPCP852':
+ case 'IBM852':
+ return 'IBM852';
+
+ case '855':
+ case 'CP855':
+ case 'CSIBM855':
+ case 'IBM855':
+ return 'IBM855';
+
+ case '857':
+ case 'CP857':
+ case 'CSIBM857':
+ case 'IBM857':
+ return 'IBM857';
+
+ case '860':
+ case 'CP860':
+ case 'CSIBM860':
+ case 'IBM860':
+ return 'IBM860';
+
+ case '861':
+ case 'CP-IS':
+ case 'CP861':
+ case 'CSIBM861':
+ case 'IBM861':
+ return 'IBM861';
+
+ case '862':
+ case 'CP862':
+ case 'CSPC862LATINHEBREW':
+ case 'IBM862':
+ return 'IBM862';
+
+ case '863':
+ case 'CP863':
+ case 'CSIBM863':
+ case 'IBM863':
+ return 'IBM863';
+
+ case 'CP864':
+ case 'CSIBM864':
+ case 'IBM864':
+ return 'IBM864';
+
+ case '865':
+ case 'CP865':
+ case 'CSIBM865':
+ case 'IBM865':
+ return 'IBM865';
+
+ case '866':
+ case 'CP866':
+ case 'CSIBM866':
+ case 'IBM866':
+ return 'IBM866';
+
+ case 'CP-AR':
+ case 'CP868':
+ case 'CSIBM868':
+ case 'IBM868':
+ return 'IBM868';
+
+ case '869':
+ case 'CP-GR':
+ case 'CP869':
+ case 'CSIBM869':
+ case 'IBM869':
+ return 'IBM869';
+
+ case 'CP870':
+ case 'CSIBM870':
+ case 'EBCDIC-CP-ROECE':
+ case 'EBCDIC-CP-YU':
+ case 'IBM870':
+ return 'IBM870';
+
+ case 'CP871':
+ case 'CSIBM871':
+ case 'EBCDIC-CP-IS':
+ case 'IBM871':
+ return 'IBM871';
+
+ case 'CP880':
+ case 'CSIBM880':
+ case 'EBCDIC-CYRILLIC':
+ case 'IBM880':
+ return 'IBM880';
+
+ case 'CP891':
+ case 'CSIBM891':
+ case 'IBM891':
+ return 'IBM891';
+
+ case 'CP903':
+ case 'CSIBM903':
+ case 'IBM903':
+ return 'IBM903';
+
+ case '904':
+ case 'CP904':
+ case 'CSIBBM904':
+ case 'IBM904':
+ return 'IBM904';
+
+ case 'CP905':
+ case 'CSIBM905':
+ case 'EBCDIC-CP-TR':
+ case 'IBM905':
+ return 'IBM905';
+
+ case 'CP918':
+ case 'CSIBM918':
+ case 'EBCDIC-CP-AR2':
+ case 'IBM918':
+ return 'IBM918';
+
+ case 'CSISO143IECP271':
+ case 'IEC_P27-1':
+ case 'ISO-IR-143':
+ return 'IEC_P27-1';
+
+ case 'CSISO49INIS':
+ case 'INIS':
+ case 'ISO-IR-49':
+ return 'INIS';
+
+ case 'CSISO50INIS8':
+ case 'INIS-8':
+ case 'ISO-IR-50':
+ return 'INIS-8';
+
+ case 'CSISO51INISCYRILLIC':
+ case 'INIS-CYRILLIC':
+ case 'ISO-IR-51':
+ return 'INIS-cyrillic';
+
+ case 'CSINVARIANT':
+ case 'INVARIANT':
+ return 'INVARIANT';
+
+ case 'ISO-10646-J-1':
+ return 'ISO-10646-J-1';
+
+ case 'CSUNICODE':
+ case 'ISO-10646-UCS-2':
+ return 'ISO-10646-UCS-2';
+
+ case 'CSUCS4':
+ case 'ISO-10646-UCS-4':
+ return 'ISO-10646-UCS-4';
+
+ case 'CSUNICODEASCII':
+ case 'ISO-10646-UCS-BASIC':
+ return 'ISO-10646-UCS-Basic';
+
+ case 'CSISO10646UTF1':
+ case 'ISO-10646-UTF-1':
+ return 'ISO-10646-UTF-1';
+
+ case 'CSUNICODELATIN1':
+ case 'ISO-10646':
+ case 'ISO-10646-UNICODE-LATIN1':
+ return 'ISO-10646-Unicode-Latin1';
+
+ case 'CSISO115481':
+ case 'ISO-11548-1':
+ case 'ISO_11548-1':
+ case 'ISO_TR_11548-1':
+ return 'ISO-11548-1';
+
+ case 'ISO-2022-CN':
+ return 'ISO-2022-CN';
+
+ case 'ISO-2022-CN-EXT':
+ return 'ISO-2022-CN-EXT';
+
+ case 'CSISO2022JP':
+ case 'ISO-2022-JP':
+ return 'ISO-2022-JP';
+
+ case 'CSISO2022JP2':
+ case 'ISO-2022-JP-2':
+ return 'ISO-2022-JP-2';
+
+ case 'CSISO2022KR':
+ case 'ISO-2022-KR':
+ return 'ISO-2022-KR';
+
+ case 'CSWINDOWS30LATIN1':
+ case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
+ return 'ISO-8859-1-Windows-3.0-Latin-1';
+
+ case 'CSWINDOWS31LATIN1':
+ case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
+ return 'ISO-8859-1-Windows-3.1-Latin-1';
+
+ case 'CSISOLATIN6':
+ case 'ISO-8859-10':
+ case 'ISO-IR-157':
+ case 'ISO_8859-10:1992':
+ case 'L6':
+ case 'LATIN6':
+ return 'ISO-8859-10';
+
+ case 'ISO-8859-13':
+ return 'ISO-8859-13';
+
+ case 'ISO-8859-14':
+ case 'ISO-CELTIC':
+ case 'ISO-IR-199':
+ case 'ISO_8859-14':
+ case 'ISO_8859-14:1998':
+ case 'L8':
+ case 'LATIN8':
+ return 'ISO-8859-14';
+
+ case 'ISO-8859-15':
+ case 'ISO_8859-15':
+ case 'LATIN-9':
+ return 'ISO-8859-15';
+
+ case 'ISO-8859-16':
+ case 'ISO-IR-226':
+ case 'ISO_8859-16':
+ case 'ISO_8859-16:2001':
+ case 'L10':
+ case 'LATIN10':
+ return 'ISO-8859-16';
+
+ case 'CSISOLATIN2':
+ case 'ISO-8859-2':
+ case 'ISO-IR-101':
+ case 'ISO_8859-2':
+ case 'ISO_8859-2:1987':
+ case 'L2':
+ case 'LATIN2':
+ return 'ISO-8859-2';
+
+ case 'CSWINDOWS31LATIN2':
+ case 'ISO-8859-2-WINDOWS-LATIN-2':
+ return 'ISO-8859-2-Windows-Latin-2';
+
+ case 'CSISOLATIN3':
+ case 'ISO-8859-3':
+ case 'ISO-IR-109':
+ case 'ISO_8859-3':
+ case 'ISO_8859-3:1988':
+ case 'L3':
+ case 'LATIN3':
+ return 'ISO-8859-3';
+
+ case 'CSISOLATIN4':
+ case 'ISO-8859-4':
+ case 'ISO-IR-110':
+ case 'ISO_8859-4':
+ case 'ISO_8859-4:1988':
+ case 'L4':
+ case 'LATIN4':
+ return 'ISO-8859-4';
+
+ case 'CSISOLATINCYRILLIC':
+ case 'CYRILLIC':
+ case 'ISO-8859-5':
+ case 'ISO-IR-144':
+ case 'ISO_8859-5':
+ case 'ISO_8859-5:1988':
+ return 'ISO-8859-5';
+
+ case 'ARABIC':
+ case 'ASMO-708':
+ case 'CSISOLATINARABIC':
+ case 'ECMA-114':
+ case 'ISO-8859-6':
+ case 'ISO-IR-127':
+ case 'ISO_8859-6':
+ case 'ISO_8859-6:1987':
+ return 'ISO-8859-6';
+
+ case 'CSISO88596E':
+ case 'ISO-8859-6-E':
+ case 'ISO_8859-6-E':
+ return 'ISO-8859-6-E';
+
+ case 'CSISO88596I':
+ case 'ISO-8859-6-I':
+ case 'ISO_8859-6-I':
+ return 'ISO-8859-6-I';
+
+ case 'CSISOLATINGREEK':
+ case 'ECMA-118':
+ case 'ELOT_928':
+ case 'GREEK':
+ case 'GREEK8':
+ case 'ISO-8859-7':
+ case 'ISO-IR-126':
+ case 'ISO_8859-7':
+ case 'ISO_8859-7:1987':
+ return 'ISO-8859-7';
+
+ case 'CSISOLATINHEBREW':
+ case 'HEBREW':
+ case 'ISO-8859-8':
+ case 'ISO-IR-138':
+ case 'ISO_8859-8':
+ case 'ISO_8859-8:1988':
+ return 'ISO-8859-8';
+
+ case 'CSISO88598E':
+ case 'ISO-8859-8-E':
+ case 'ISO_8859-8-E':
+ return 'ISO-8859-8-E';
+
+ case 'CSISO88598I':
+ case 'ISO-8859-8-I':
+ case 'ISO_8859-8-I':
+ return 'ISO-8859-8-I';
+
+ case 'CSISOLATIN5':
+ case 'ISO-8859-9':
+ case 'ISO-IR-148':
+ case 'ISO_8859-9':
+ case 'ISO_8859-9:1989':
+ case 'L5':
+ case 'LATIN5':
+ return 'ISO-8859-9';
+
+ case 'CSWINDOWS31LATIN5':
+ case 'ISO-8859-9-WINDOWS-LATIN-5':
+ return 'ISO-8859-9-Windows-Latin-5';
+
+ case 'CSUNICODEIBM1261':
+ case 'ISO-UNICODE-IBM-1261':
+ return 'ISO-Unicode-IBM-1261';
+
+ case 'CSUNICODEIBM1264':
+ case 'ISO-UNICODE-IBM-1264':
+ return 'ISO-Unicode-IBM-1264';
+
+ case 'CSUNICODEIBM1265':
+ case 'ISO-UNICODE-IBM-1265':
+ return 'ISO-Unicode-IBM-1265';
+
+ case 'CSUNICODEIBM1268':
+ case 'ISO-UNICODE-IBM-1268':
+ return 'ISO-Unicode-IBM-1268';
+
+ case 'CSUNICODEIBM1276':
+ case 'ISO-UNICODE-IBM-1276':
+ return 'ISO-Unicode-IBM-1276';
+
+ case 'CSISO10367BOX':
+ case 'ISO-IR-155':
+ case 'ISO_10367-BOX':
+ return 'ISO_10367-box';
+
+ case 'CSISO2033':
+ case 'E13B':
+ case 'ISO-IR-98':
+ case 'ISO_2033-1983':
+ return 'ISO_2033-1983';
+
+ case 'CSISO5427CYRILLIC':
+ case 'ISO-IR-37':
+ case 'ISO_5427':
+ return 'ISO_5427';
+
+ case 'ISO-IR-54':
+ case 'ISO5427CYRILLIC1981':
+ case 'ISO_5427:1981':
+ return 'ISO_5427:1981';
+
+ case 'CSISO5428GREEK':
+ case 'ISO-IR-55':
+ case 'ISO_5428:1980':
+ return 'ISO_5428:1980';
+
+ case 'CSISO646BASIC1983':
+ case 'ISO_646.BASIC:1983':
+ case 'REF':
+ return 'ISO_646.basic:1983';
+
+ case 'CSISO2INTLREFVERSION':
+ case 'IRV':
+ case 'ISO-IR-2':
+ case 'ISO_646.IRV:1983':
+ return 'ISO_646.irv:1983';
+
+ case 'CSISO6937ADD':
+ case 'ISO-IR-152':
+ case 'ISO_6937-2-25':
+ return 'ISO_6937-2-25';
+
+ case 'CSISOTEXTCOMM':
+ case 'ISO-IR-142':
+ case 'ISO_6937-2-ADD':
+ return 'ISO_6937-2-add';
+
+ case 'CSISO8859SUPP':
+ case 'ISO-IR-154':
+ case 'ISO_8859-SUPP':
+ case 'LATIN1-2-5':
+ return 'ISO_8859-supp';
+
+ case 'CSISO15ITALIAN':
+ case 'ISO-IR-15':
+ case 'ISO646-IT':
+ case 'IT':
+ return 'IT';
+
+ case 'CSISO13JISC6220JP':
+ case 'ISO-IR-13':
+ case 'JIS_C6220-1969':
+ case 'JIS_C6220-1969-JP':
+ case 'KATAKANA':
+ case 'X0201-7':
+ return 'JIS_C6220-1969-jp';
+
+ case 'CSISO14JISC6220RO':
+ case 'ISO-IR-14':
+ case 'ISO646-JP':
+ case 'JIS_C6220-1969-RO':
+ case 'JP':
+ return 'JIS_C6220-1969-ro';
+
+ case 'CSISO42JISC62261978':
+ case 'ISO-IR-42':
+ case 'JIS_C6226-1978':
+ return 'JIS_C6226-1978';
+
+ case 'CSISO87JISX0208':
+ case 'ISO-IR-87':
+ case 'JIS_C6226-1983':
+ case 'JIS_X0208-1983':
+ case 'X0208':
+ return 'JIS_C6226-1983';
+
+ case 'CSISO91JISC62291984A':
+ case 'ISO-IR-91':
+ case 'JIS_C6229-1984-A':
+ case 'JP-OCR-A':
+ return 'JIS_C6229-1984-a';
+
+ case 'CSISO92JISC62991984B':
+ case 'ISO-IR-92':
+ case 'ISO646-JP-OCR-B':
+ case 'JIS_C6229-1984-B':
+ case 'JP-OCR-B':
+ return 'JIS_C6229-1984-b';
+
+ case 'CSISO93JIS62291984BADD':
+ case 'ISO-IR-93':
+ case 'JIS_C6229-1984-B-ADD':
+ case 'JP-OCR-B-ADD':
+ return 'JIS_C6229-1984-b-add';
+
+ case 'CSISO94JIS62291984HAND':
+ case 'ISO-IR-94':
+ case 'JIS_C6229-1984-HAND':
+ case 'JP-OCR-HAND':
+ return 'JIS_C6229-1984-hand';
+
+ case 'CSISO95JIS62291984HANDADD':
+ case 'ISO-IR-95':
+ case 'JIS_C6229-1984-HAND-ADD':
+ case 'JP-OCR-HAND-ADD':
+ return 'JIS_C6229-1984-hand-add';
+
+ case 'CSISO96JISC62291984KANA':
+ case 'ISO-IR-96':
+ case 'JIS_C6229-1984-KANA':
+ return 'JIS_C6229-1984-kana';
+
+ case 'CSJISENCODING':
+ case 'JIS_ENCODING':
+ return 'JIS_Encoding';
+
+ case 'CSHALFWIDTHKATAKANA':
+ case 'JIS_X0201':
+ case 'X0201':
+ return 'JIS_X0201';
+
+ case 'CSISO159JISX02121990':
+ case 'ISO-IR-159':
+ case 'JIS_X0212-1990':
+ case 'X0212':
+ return 'JIS_X0212-1990';
+
+ case 'CSISO141JUSIB1002':
+ case 'ISO-IR-141':
+ case 'ISO646-YU':
+ case 'JS':
+ case 'JUS_I.B1.002':
+ case 'YU':
+ return 'JUS_I.B1.002';
+
+ case 'CSISO147MACEDONIAN':
+ case 'ISO-IR-147':
+ case 'JUS_I.B1.003-MAC':
+ case 'MACEDONIAN':
+ return 'JUS_I.B1.003-mac';
+
+ case 'CSISO146SERBIAN':
+ case 'ISO-IR-146':
+ case 'JUS_I.B1.003-SERB':
+ case 'SERBIAN':
+ return 'JUS_I.B1.003-serb';
+
+ case 'KOI7-SWITCHED':
+ return 'KOI7-switched';
+
+ case 'CSKOI8R':
+ case 'KOI8-R':
+ return 'KOI8-R';
+
+ case 'KOI8-U':
+ return 'KOI8-U';
+
+ case 'CSKSC5636':
+ case 'ISO646-KR':
+ case 'KSC5636':
+ return 'KSC5636';
+
+ case 'CSKSC56011987':
+ case 'ISO-IR-149':
+ case 'KOREAN':
+ case 'KSC_5601':
+ case 'KS_C_5601-1987':
+ case 'KS_C_5601-1989':
+ return 'KS_C_5601-1987';
+
+ case 'CSKZ1048':
+ case 'KZ-1048':
+ case 'RK1048':
+ case 'STRK1048-2002':
+ return 'KZ-1048';
+
+ case 'CSISO27LATINGREEK1':
+ case 'ISO-IR-27':
+ case 'LATIN-GREEK-1':
+ return 'Latin-greek-1';
+
+ case 'CSMNEM':
+ case 'MNEM':
+ return 'MNEM';
+
+ case 'CSMNEMONIC':
+ case 'MNEMONIC':
+ return 'MNEMONIC';
+
+ case 'CSISO86HUNGARIAN':
+ case 'HU':
+ case 'ISO-IR-86':
+ case 'ISO646-HU':
+ case 'MSZ_7795.3':
+ return 'MSZ_7795.3';
+
+ case 'CSMICROSOFTPUBLISHING':
+ case 'MICROSOFT-PUBLISHING':
+ return 'Microsoft-Publishing';
+
+ case 'CSNATSDANO':
+ case 'ISO-IR-9-1':
+ case 'NATS-DANO':
+ return 'NATS-DANO';
+
+ case 'CSNATSDANOADD':
+ case 'ISO-IR-9-2':
+ case 'NATS-DANO-ADD':
+ return 'NATS-DANO-ADD';
+
+ case 'CSNATSSEFI':
+ case 'ISO-IR-8-1':
+ case 'NATS-SEFI':
+ return 'NATS-SEFI';
+
+ case 'CSNATSSEFIADD':
+ case 'ISO-IR-8-2':
+ case 'NATS-SEFI-ADD':
+ return 'NATS-SEFI-ADD';
+
+ case 'CSISO151CUBA':
+ case 'CUBA':
+ case 'ISO-IR-151':
+ case 'ISO646-CU':
+ case 'NC_NC00-10:81':
+ return 'NC_NC00-10:81';
+
+ case 'CSISO69FRENCH':
+ case 'FR':
+ case 'ISO-IR-69':
+ case 'ISO646-FR':
+ case 'NF_Z_62-010':
+ return 'NF_Z_62-010';
+
+ case 'CSISO25FRENCH':
+ case 'ISO-IR-25':
+ case 'ISO646-FR1':
+ case 'NF_Z_62-010_(1973)':
+ return 'NF_Z_62-010_(1973)';
+
+ case 'CSISO60DANISHNORWEGIAN':
+ case 'CSISO60NORWEGIAN1':
+ case 'ISO-IR-60':
+ case 'ISO646-NO':
+ case 'NO':
+ case 'NS_4551-1':
+ return 'NS_4551-1';
+
+ case 'CSISO61NORWEGIAN2':
+ case 'ISO-IR-61':
+ case 'ISO646-NO2':
+ case 'NO2':
+ case 'NS_4551-2':
+ return 'NS_4551-2';
+
+ case 'OSD_EBCDIC_DF03_IRV':
+ return 'OSD_EBCDIC_DF03_IRV';
+
+ case 'OSD_EBCDIC_DF04_1':
+ return 'OSD_EBCDIC_DF04_1';
+
+ case 'OSD_EBCDIC_DF04_15':
+ return 'OSD_EBCDIC_DF04_15';
+
+ case 'CSPC8DANISHNORWEGIAN':
+ case 'PC8-DANISH-NORWEGIAN':
+ return 'PC8-Danish-Norwegian';
+
+ case 'CSPC8TURKISH':
+ case 'PC8-TURKISH':
+ return 'PC8-Turkish';
+
+ case 'CSISO16PORTUGUESE':
+ case 'ISO-IR-16':
+ case 'ISO646-PT':
+ case 'PT':
+ return 'PT';
+
+ case 'CSISO84PORTUGUESE2':
+ case 'ISO-IR-84':
+ case 'ISO646-PT2':
+ case 'PT2':
+ return 'PT2';
+
+ case 'CP154':
+ case 'CSPTCP154':
+ case 'CYRILLIC-ASIAN':
+ case 'PT154':
+ case 'PTCP154':
+ return 'PTCP154';
+
+ case 'SCSU':
+ return 'SCSU';
+
+ case 'CSISO10SWEDISH':
+ case 'FI':
+ case 'ISO-IR-10':
+ case 'ISO646-FI':
+ case 'ISO646-SE':
+ case 'SE':
+ case 'SEN_850200_B':
+ return 'SEN_850200_B';
+
+ case 'CSISO11SWEDISHFORNAMES':
+ case 'ISO-IR-11':
+ case 'ISO646-SE2':
+ case 'SE2':
+ case 'SEN_850200_C':
+ return 'SEN_850200_C';
+
+ case 'CSSHIFTJIS':
+ case 'MS_KANJI':
+ case 'SHIFT_JIS':
+ return 'Shift_JIS';
+
+ case 'CSISO128T101G2':
+ case 'ISO-IR-128':
+ case 'T.101-G2':
+ return 'T.101-G2';
+
+ case 'CSISO102T617BIT':
+ case 'ISO-IR-102':
+ case 'T.61-7BIT':
+ return 'T.61-7bit';
+
+ case 'CSISO103T618BIT':
+ case 'ISO-IR-103':
+ case 'T.61':
+ case 'T.61-8BIT':
+ return 'T.61-8bit';
+
+ case 'CSTSCII':
+ case 'TSCII':
+ return 'TSCII';
+
+ case 'CSUNICODE11':
+ case 'UNICODE-1-1':
+ return 'UNICODE-1-1';
+
+ case 'CSUNICODE11UTF7':
+ case 'UNICODE-1-1-UTF-7':
+ return 'UNICODE-1-1-UTF-7';
+
+ case 'CSUNKNOWN8BIT':
+ case 'UNKNOWN-8BIT':
+ return 'UNKNOWN-8BIT';
+
+ case 'ANSI':
+ case 'ANSI_X3.4-1968':
+ case 'ANSI_X3.4-1986':
+ case 'ASCII':
+ case 'CP367':
+ case 'CSASCII':
+ case 'IBM367':
+ case 'ISO-IR-6':
+ case 'ISO646-US':
+ case 'ISO_646.IRV:1991':
+ case 'US':
+ case 'US-ASCII':
+ return 'US-ASCII';
+
+ case 'UTF-16':
+ return 'UTF-16';
+
+ case 'UTF-16BE':
+ return 'UTF-16BE';
+
+ case 'UTF-16LE':
+ return 'UTF-16LE';
+
+ case 'UTF-32':
+ return 'UTF-32';
+
+ case 'UTF-32BE':
+ return 'UTF-32BE';
+
+ case 'UTF-32LE':
+ return 'UTF-32LE';
+
+ case 'UTF-7':
+ return 'UTF-7';
+
+ case 'UTF-8':
+ return 'UTF-8';
+
+ case 'CSVIQR':
+ case 'VIQR':
+ return 'VIQR';
+
+ case 'CSVISCII':
+ case 'VISCII':
+ return 'VISCII';
+
+ case 'CSVENTURAINTERNATIONAL':
+ case 'VENTURA-INTERNATIONAL':
+ return 'Ventura-International';
+
+ case 'CSVENTURAMATH':
+ case 'VENTURA-MATH':
+ return 'Ventura-Math';
+
+ case 'CSVENTURAUS':
+ case 'VENTURA-US':
+ return 'Ventura-US';
+
+ case 'CSWINDOWS31J':
+ case 'WINDOWS-31J':
+ return 'Windows-31J';
+
+ case 'CSDKUS':
+ case 'DK-US':
+ return 'dk-us';
+
+ case 'CSISO150':
+ case 'CSISO150GREEKCCITT':
+ case 'GREEK-CCITT':
+ case 'ISO-IR-150':
+ return 'greek-ccitt';
+
+ case 'CSISO88GREEK7':
+ case 'GREEK7':
+ case 'ISO-IR-88':
+ return 'greek7';
+
+ case 'CSISO18GREEK7OLD':
+ case 'GREEK7-OLD':
+ case 'ISO-IR-18':
+ return 'greek7-old';
+
+ case 'CSHPROMAN8':
+ case 'HP-ROMAN8':
+ case 'R8':
+ case 'ROMAN8':
+ return 'hp-roman8';
+
+ case 'CSISO90':
+ case 'ISO-IR-90':
+ return 'iso-ir-90';
+
+ case 'CSISO19LATINGREEK':
+ case 'ISO-IR-19':
+ case 'LATIN-GREEK':
+ return 'latin-greek';
+
+ case 'CSISO158LAP':
+ case 'ISO-IR-158':
+ case 'LAP':
+ case 'LATIN-LAP':
+ return 'latin-lap';
+
+ case 'CSMACINTOSH':
+ case 'MAC':
+ case 'MACINTOSH':
+ return 'macintosh';
+
+ case 'CSUSDK':
+ case 'US-DK':
+ return 'us-dk';
+
+ case 'CSISO70VIDEOTEXSUPP1':
+ case 'ISO-IR-70':
+ case 'VIDEOTEX-SUPPL':
+ return 'videotex-suppl';
+
+ case 'WINDOWS-1250':
+ return 'windows-1250';
+
+ case 'WINDOWS-1251':
+ return 'windows-1251';
+
+ case 'CP819':
+ case 'CSISOLATIN1':
+ case 'IBM819':
+ case 'ISO-8859-1':
+ case 'ISO-IR-100':
+ case 'ISO_8859-1':
+ case 'ISO_8859-1:1987':
+ case 'L1':
+ case 'LATIN1':
+ case 'WINDOWS-1252':
+ return 'windows-1252';
+
+ case 'WINDOWS-1253':
+ return 'windows-1253';
+
+ case 'WINDOWS-1254':
+ return 'windows-1254';
+
+ case 'WINDOWS-1255':
+ return 'windows-1255';
+
+ case 'WINDOWS-1256':
+ return 'windows-1256';
+
+ case 'WINDOWS-1257':
+ return 'windows-1257';
+
+ case 'WINDOWS-1258':
+ return 'windows-1258';
+
+ default:
+ return $encoding;
+ }
+ }
+
+ function get_curl_version()
+ {
+ if (is_array($curl = curl_version()))
+ {
+ $curl = $curl['version'];
+ }
+ elseif (substr($curl, 0, 5) == 'curl/')
+ {
+ $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
+ }
+ elseif (substr($curl, 0, 8) == 'libcurl/')
+ {
+ $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
+ }
+ else
+ {
+ $curl = 0;
+ }
+ return $curl;
+ }
+
+ function is_subclass_of($class1, $class2)
+ {
+ if (func_num_args() != 2)
+ {
+ trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
+ }
+ elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
+ {
+ return is_subclass_of($class1, $class2);
+ }
+ elseif (is_string($class1) && is_string($class2))
+ {
+ if (class_exists($class1))
+ {
+ if (class_exists($class2))
+ {
+ $class2 = strtolower($class2);
+ while ($class1 = strtolower(get_parent_class($class1)))
+ {
+ if ($class1 == $class2)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ else
+ {
+ trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Strip HTML comments
+ *
+ * @access public
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ function strip_comments($data)
+ {
+ $output = '';
+ while (($start = strpos($data, '', $start)) !== false)
+ {
+ $data = substr_replace($data, '', 0, $end + 3);
+ }
+ else
+ {
+ $data = '';
+ }
+ }
+ return $output . $data;
+ }
+
+ function parse_date($dt)
+ {
+ $parser = SimplePie_Parse_Date::get();
+ return $parser->parse($dt);
+ }
+
+ /**
+ * Decode HTML entities
+ *
+ * @static
+ * @access public
+ * @param string $data Input data
+ * @return string Output data
+ */
+ function entities_decode($data)
+ {
+ $decoder = new SimplePie_Decode_HTML_Entities($data);
+ return $decoder->parse();
+ }
+
+ /**
+ * Remove RFC822 comments
+ *
+ * @access public
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ function uncomment_rfc822($string)
+ {
+ $string = (string) $string;
+ $position = 0;
+ $length = strlen($string);
+ $depth = 0;
+
+ $output = '';
+
+ while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
+ {
+ $output .= substr($string, $position, $pos - $position);
+ $position = $pos + 1;
+ if ($string[$pos - 1] !== '\\')
+ {
+ $depth++;
+ while ($depth && $position < $length)
+ {
+ $position += strcspn($string, '()', $position);
+ if ($string[$position - 1] === '\\')
+ {
+ $position++;
+ continue;
+ }
+ elseif (isset($string[$position]))
+ {
+ switch ($string[$position])
+ {
+ case '(':
+ $depth++;
+ break;
+
+ case ')':
+ $depth--;
+ break;
+ }
+ $position++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ $output .= '(';
+ }
+ }
+ $output .= substr($string, $position);
+
+ return $output;
+ }
+
+ function parse_mime($mime)
+ {
+ if (($pos = strpos($mime, ';')) === false)
+ {
+ return trim($mime);
+ }
+ else
+ {
+ return trim(substr($mime, 0, $pos));
+ }
+ }
+
+ function htmlspecialchars_decode($string, $quote_style)
+ {
+ if (function_exists('htmlspecialchars_decode'))
+ {
+ return htmlspecialchars_decode($string, $quote_style);
+ }
+ else
+ {
+ return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
+ }
+ }
+
+ function atom_03_construct_type($attribs)
+ {
+ if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
+ {
+ $mode = SIMPLEPIE_CONSTRUCT_BASE64;
+ }
+ else
+ {
+ $mode = SIMPLEPIE_CONSTRUCT_NONE;
+ }
+ if (isset($attribs['']['type']))
+ {
+ switch (strtolower(trim($attribs['']['type'])))
+ {
+ case 'text':
+ case 'text/plain':
+ return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
+
+ case 'html':
+ case 'text/html':
+ return SIMPLEPIE_CONSTRUCT_HTML | $mode;
+
+ case 'xhtml':
+ case 'application/xhtml+xml':
+ return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
+
+ default:
+ return SIMPLEPIE_CONSTRUCT_NONE | $mode;
+ }
+ }
+ else
+ {
+ return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
+ }
+ }
+
+ function atom_10_construct_type($attribs)
+ {
+ if (isset($attribs['']['type']))
+ {
+ switch (strtolower(trim($attribs['']['type'])))
+ {
+ case 'text':
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+
+ case 'html':
+ return SIMPLEPIE_CONSTRUCT_HTML;
+
+ case 'xhtml':
+ return SIMPLEPIE_CONSTRUCT_XHTML;
+
+ default:
+ return SIMPLEPIE_CONSTRUCT_NONE;
+ }
+ }
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+ }
+
+ function atom_10_content_construct_type($attribs)
+ {
+ if (isset($attribs['']['type']))
+ {
+ $type = strtolower(trim($attribs['']['type']));
+ switch ($type)
+ {
+ case 'text':
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+
+ case 'html':
+ return SIMPLEPIE_CONSTRUCT_HTML;
+
+ case 'xhtml':
+ return SIMPLEPIE_CONSTRUCT_XHTML;
+ }
+ if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
+ {
+ return SIMPLEPIE_CONSTRUCT_NONE;
+ }
+ else
+ {
+ return SIMPLEPIE_CONSTRUCT_BASE64;
+ }
+ }
+ else
+ {
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+ }
+ }
+
+ function is_isegment_nz_nc($string)
+ {
+ return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);
+ }
+
+ function space_seperated_tokens($string)
+ {
+ $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
+ $string_length = strlen($string);
+
+ $position = strspn($string, $space_characters);
+ $tokens = array();
+
+ while ($position < $string_length)
+ {
+ $len = strcspn($string, $space_characters, $position);
+ $tokens[] = substr($string, $position, $len);
+ $position += $len;
+ $position += strspn($string, $space_characters, $position);
+ }
+
+ return $tokens;
+ }
+
+ function array_unique($array)
+ {
+ if (version_compare(PHP_VERSION, '5.2', '>='))
+ {
+ return array_unique($array);
+ }
+ else
+ {
+ $array = (array) $array;
+ $new_array = array();
+ $new_array_strings = array();
+ foreach ($array as $key => $value)
+ {
+ if (is_object($value))
+ {
+ if (method_exists($value, '__toString'))
+ {
+ $cmp = $value->__toString();
+ }
+ else
+ {
+ trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
+ }
+ }
+ elseif (is_array($value))
+ {
+ $cmp = (string) reset($value);
+ }
+ else
+ {
+ $cmp = (string) $value;
+ }
+ if (!in_array($cmp, $new_array_strings))
+ {
+ $new_array[$key] = $value;
+ $new_array_strings[] = $cmp;
+ }
+ }
+ return $new_array;
+ }
+ }
+
+ /**
+ * Converts a unicode codepoint to a UTF-8 character
+ *
+ * @static
+ * @access public
+ * @param int $codepoint Unicode codepoint
+ * @return string UTF-8 character
+ */
+ function codepoint_to_utf8($codepoint)
+ {
+ static $cache = array();
+ $codepoint = (int) $codepoint;
+ if (isset($cache[$codepoint]))
+ {
+ return $cache[$codepoint];
+ }
+ elseif ($codepoint < 0)
+ {
+ return $cache[$codepoint] = false;
+ }
+ else if ($codepoint <= 0x7f)
+ {
+ return $cache[$codepoint] = chr($codepoint);
+ }
+ else if ($codepoint <= 0x7ff)
+ {
+ return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
+ }
+ else if ($codepoint <= 0xffff)
+ {
+ return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
+ }
+ else if ($codepoint <= 0x10ffff)
+ {
+ return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
+ }
+ else
+ {
+ // U+FFFD REPLACEMENT CHARACTER
+ return $cache[$codepoint] = "\xEF\xBF\xBD";
+ }
+ }
+
+ /**
+ * Re-implementation of PHP 5's stripos()
+ *
+ * Returns the numeric position of the first occurrence of needle in the
+ * haystack string.
+ *
+ * @static
+ * @access string
+ * @param object $haystack
+ * @param string $needle Note that the needle may be a string of one or more
+ * characters. If needle is not a string, it is converted to an integer
+ * and applied as the ordinal value of a character.
+ * @param int $offset The optional offset parameter allows you to specify which
+ * character in haystack to start searching. The position returned is still
+ * relative to the beginning of haystack.
+ * @return bool If needle is not found, stripos() will return boolean false.
+ */
+ function stripos($haystack, $needle, $offset = 0)
+ {
+ if (function_exists('stripos'))
+ {
+ return stripos($haystack, $needle, $offset);
+ }
+ else
+ {
+ if (is_string($needle))
+ {
+ $needle = strtolower($needle);
+ }
+ elseif (is_int($needle) || is_bool($needle) || is_double($needle))
+ {
+ $needle = strtolower(chr($needle));
+ }
+ else
+ {
+ trigger_error('needle is not a string or an integer', E_USER_WARNING);
+ return false;
+ }
+
+ return strpos(strtolower($haystack), $needle, $offset);
+ }
+ }
+
+ /**
+ * Similar to parse_str()
+ *
+ * Returns an associative array of name/value pairs, where the value is an
+ * array of values that have used the same name
+ *
+ * @static
+ * @access string
+ * @param string $str The input string.
+ * @return array
+ */
+ function parse_str($str)
+ {
+ $return = array();
+ $str = explode('&', $str);
+
+ foreach ($str as $section)
+ {
+ if (strpos($section, '=') !== false)
+ {
+ list($name, $value) = explode('=', $section, 2);
+ $return[urldecode($name)][] = urldecode($value);
+ }
+ else
+ {
+ $return[urldecode($section)][] = null;
+ }
+ }
+
+ return $return;
+ }
+
+ /**
+ * Detect XML encoding, as per XML 1.0 Appendix F.1
+ *
+ * @todo Add support for EBCDIC
+ * @param string $data XML data
+ * @return array Possible encodings
+ */
+ function xml_encoding($data)
+ {
+ // UTF-32 Big Endian BOM
+ if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
+ {
+ $encoding[] = 'UTF-32BE';
+ }
+ // UTF-32 Little Endian BOM
+ elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
+ {
+ $encoding[] = 'UTF-32LE';
+ }
+ // UTF-16 Big Endian BOM
+ elseif (substr($data, 0, 2) === "\xFE\xFF")
+ {
+ $encoding[] = 'UTF-16BE';
+ }
+ // UTF-16 Little Endian BOM
+ elseif (substr($data, 0, 2) === "\xFF\xFE")
+ {
+ $encoding[] = 'UTF-16LE';
+ }
+ // UTF-8 BOM
+ elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
+ {
+ $encoding[] = 'UTF-8';
+ }
+ // UTF-32 Big Endian Without BOM
+ elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
+ {
+ if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
+ {
+ $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-32BE';
+ }
+ // UTF-32 Little Endian Without BOM
+ elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
+ {
+ if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
+ {
+ $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-32LE';
+ }
+ // UTF-16 Big Endian Without BOM
+ elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
+ {
+ if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
+ {
+ $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-16BE';
+ }
+ // UTF-16 Little Endian Without BOM
+ elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
+ {
+ if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
+ {
+ $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-16LE';
+ }
+ // US-ASCII (or superset)
+ elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
+ {
+ if ($pos = strpos($data, "\x3F\x3E"))
+ {
+ $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-8';
+ }
+ // Fallback to UTF-8
+ else
+ {
+ $encoding[] = 'UTF-8';
+ }
+ return $encoding;
+ }
+}
+
+/**
+ * Decode HTML Entities
+ *
+ * This implements HTML5 as of revision 967 (2007-06-28)
+ *
+ * @package SimplePie
+ */
+class SimplePie_Decode_HTML_Entities
+{
+ /**
+ * Data to be parsed
+ *
+ * @access private
+ * @var string
+ */
+ var $data = '';
+
+ /**
+ * Currently consumed bytes
+ *
+ * @access private
+ * @var string
+ */
+ var $consumed = '';
+
+ /**
+ * Position of the current byte being parsed
+ *
+ * @access private
+ * @var int
+ */
+ var $position = 0;
+
+ /**
+ * Create an instance of the class with the input data
+ *
+ * @access public
+ * @param string $data Input data
+ */
+ function SimplePie_Decode_HTML_Entities($data)
+ {
+ $this->data = $data;
+ }
+
+ /**
+ * Parse the input data
+ *
+ * @access public
+ * @return string Output data
+ */
+ function parse()
+ {
+ while (($this->position = strpos($this->data, '&', $this->position)) !== false)
+ {
+ $this->consume();
+ $this->entity();
+ $this->consumed = '';
+ }
+ return $this->data;
+ }
+
+ /**
+ * Consume the next byte
+ *
+ * @access private
+ * @return mixed The next byte, or false, if there is no more data
+ */
+ function consume()
+ {
+ if (isset($this->data[$this->position]))
+ {
+ $this->consumed .= $this->data[$this->position];
+ return $this->data[$this->position++];
+ }
+ else
+ {
+ $this->consumed = false;
+ return false;
+ }
+ }
+
+ /**
+ * Consume a range of characters
+ *
+ * @access private
+ * @param string $chars Characters to consume
+ * @return mixed A series of characters that match the range, or false
+ */
+ function consume_range($chars)
+ {
+ if ($len = strspn($this->data, $chars, $this->position))
+ {
+ $data = substr($this->data, $this->position, $len);
+ $this->consumed .= $data;
+ $this->position += $len;
+ return $data;
+ }
+ else
+ {
+ $this->consumed = false;
+ return false;
+ }
+ }
+
+ /**
+ * Unconsume one byte
+ *
+ * @access private
+ */
+ function unconsume()
+ {
+ $this->consumed = substr($this->consumed, 0, -1);
+ $this->position--;
+ }
+
+ /**
+ * Decode an entity
+ *
+ * @access private
+ */
+ function entity()
+ {
+ switch ($this->consume())
+ {
+ case "\x09":
+ case "\x0A":
+ case "\x0B":
+ case "\x0B":
+ case "\x0C":
+ case "\x20":
+ case "\x3C":
+ case "\x26":
+ case false:
+ break;
+
+ case "\x23":
+ switch ($this->consume())
+ {
+ case "\x78":
+ case "\x58":
+ $range = '0123456789ABCDEFabcdef';
+ $hex = true;
+ break;
+
+ default:
+ $range = '0123456789';
+ $hex = false;
+ $this->unconsume();
+ break;
+ }
+
+ if ($codepoint = $this->consume_range($range))
+ {
+ static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
+
+ if ($hex)
+ {
+ $codepoint = hexdec($codepoint);
+ }
+ else
+ {
+ $codepoint = intval($codepoint);
+ }
+
+ if (isset($windows_1252_specials[$codepoint]))
+ {
+ $replacement = $windows_1252_specials[$codepoint];
+ }
+ else
+ {
+ $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
+ }
+
+ if ($this->consume() != ';')
+ {
+ $this->unconsume();
+ }
+
+ $consumed_length = strlen($this->consumed);
+ $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
+ $this->position += strlen($replacement) - $consumed_length;
+ }
+ break;
+
+ default:
+ static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C");
+
+ for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
+ {
+ $consumed = substr($this->consumed, 1);
+ if (isset($entities[$consumed]))
+ {
+ $match = $consumed;
+ }
+ }
+
+ if ($match !== null)
+ {
+ $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
+ $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
+ }
+ break;
+ }
+ }
+}
+
+/**
+ * Date Parser
+ *
+ * @package SimplePie
+ */
+class SimplePie_Parse_Date
+{
+ /**
+ * Input data
+ *
+ * @access protected
+ * @var string
+ */
+ var $date;
+
+ /**
+ * List of days, calendar day name => ordinal day number in the week
+ *
+ * @access protected
+ * @var array
+ */
+ var $day = array(
+ // English
+ 'mon' => 1,
+ 'monday' => 1,
+ 'tue' => 2,
+ 'tuesday' => 2,
+ 'wed' => 3,
+ 'wednesday' => 3,
+ 'thu' => 4,
+ 'thursday' => 4,
+ 'fri' => 5,
+ 'friday' => 5,
+ 'sat' => 6,
+ 'saturday' => 6,
+ 'sun' => 7,
+ 'sunday' => 7,
+ // Dutch
+ 'maandag' => 1,
+ 'dinsdag' => 2,
+ 'woensdag' => 3,
+ 'donderdag' => 4,
+ 'vrijdag' => 5,
+ 'zaterdag' => 6,
+ 'zondag' => 7,
+ // French
+ 'lundi' => 1,
+ 'mardi' => 2,
+ 'mercredi' => 3,
+ 'jeudi' => 4,
+ 'vendredi' => 5,
+ 'samedi' => 6,
+ 'dimanche' => 7,
+ // German
+ 'montag' => 1,
+ 'dienstag' => 2,
+ 'mittwoch' => 3,
+ 'donnerstag' => 4,
+ 'freitag' => 5,
+ 'samstag' => 6,
+ 'sonnabend' => 6,
+ 'sonntag' => 7,
+ // Italian
+ 'lunedì' => 1,
+ 'martedì' => 2,
+ 'mercoledì' => 3,
+ 'giovedì' => 4,
+ 'venerdì' => 5,
+ 'sabato' => 6,
+ 'domenica' => 7,
+ // Spanish
+ 'lunes' => 1,
+ 'martes' => 2,
+ 'miércoles' => 3,
+ 'jueves' => 4,
+ 'viernes' => 5,
+ 'sábado' => 6,
+ 'domingo' => 7,
+ // Finnish
+ 'maanantai' => 1,
+ 'tiistai' => 2,
+ 'keskiviikko' => 3,
+ 'torstai' => 4,
+ 'perjantai' => 5,
+ 'lauantai' => 6,
+ 'sunnuntai' => 7,
+ // Hungarian
+ 'hétfő' => 1,
+ 'kedd' => 2,
+ 'szerda' => 3,
+ 'csütörtok' => 4,
+ 'péntek' => 5,
+ 'szombat' => 6,
+ 'vasárnap' => 7,
+ // Greek
+ 'Δευ' => 1,
+ 'Τρι' => 2,
+ 'Τετ' => 3,
+ 'Πεμ' => 4,
+ 'Παρ' => 5,
+ 'Σαβ' => 6,
+ 'Κυρ' => 7,
+ );
+
+ /**
+ * List of months, calendar month name => calendar month number
+ *
+ * @access protected
+ * @var array
+ */
+ var $month = array(
+ // English
+ 'jan' => 1,
+ 'january' => 1,
+ 'feb' => 2,
+ 'february' => 2,
+ 'mar' => 3,
+ 'march' => 3,
+ 'apr' => 4,
+ 'april' => 4,
+ 'may' => 5,
+ // No long form of May
+ 'jun' => 6,
+ 'june' => 6,
+ 'jul' => 7,
+ 'july' => 7,
+ 'aug' => 8,
+ 'august' => 8,
+ 'sep' => 9,
+ 'september' => 8,
+ 'oct' => 10,
+ 'october' => 10,
+ 'nov' => 11,
+ 'november' => 11,
+ 'dec' => 12,
+ 'december' => 12,
+ // Dutch
+ 'januari' => 1,
+ 'februari' => 2,
+ 'maart' => 3,
+ 'april' => 4,
+ 'mei' => 5,
+ 'juni' => 6,
+ 'juli' => 7,
+ 'augustus' => 8,
+ 'september' => 9,
+ 'oktober' => 10,
+ 'november' => 11,
+ 'december' => 12,
+ // French
+ 'janvier' => 1,
+ 'février' => 2,
+ 'mars' => 3,
+ 'avril' => 4,
+ 'mai' => 5,
+ 'juin' => 6,
+ 'juillet' => 7,
+ 'août' => 8,
+ 'septembre' => 9,
+ 'octobre' => 10,
+ 'novembre' => 11,
+ 'décembre' => 12,
+ // German
+ 'januar' => 1,
+ 'februar' => 2,
+ 'märz' => 3,
+ 'april' => 4,
+ 'mai' => 5,
+ 'juni' => 6,
+ 'juli' => 7,
+ 'august' => 8,
+ 'september' => 9,
+ 'oktober' => 10,
+ 'november' => 11,
+ 'dezember' => 12,
+ // Italian
+ 'gennaio' => 1,
+ 'febbraio' => 2,
+ 'marzo' => 3,
+ 'aprile' => 4,
+ 'maggio' => 5,
+ 'giugno' => 6,
+ 'luglio' => 7,
+ 'agosto' => 8,
+ 'settembre' => 9,
+ 'ottobre' => 10,
+ 'novembre' => 11,
+ 'dicembre' => 12,
+ // Spanish
+ 'enero' => 1,
+ 'febrero' => 2,
+ 'marzo' => 3,
+ 'abril' => 4,
+ 'mayo' => 5,
+ 'junio' => 6,
+ 'julio' => 7,
+ 'agosto' => 8,
+ 'septiembre' => 9,
+ 'setiembre' => 9,
+ 'octubre' => 10,
+ 'noviembre' => 11,
+ 'diciembre' => 12,
+ // Finnish
+ 'tammikuu' => 1,
+ 'helmikuu' => 2,
+ 'maaliskuu' => 3,
+ 'huhtikuu' => 4,
+ 'toukokuu' => 5,
+ 'kesäkuu' => 6,
+ 'heinäkuu' => 7,
+ 'elokuu' => 8,
+ 'suuskuu' => 9,
+ 'lokakuu' => 10,
+ 'marras' => 11,
+ 'joulukuu' => 12,
+ // Hungarian
+ 'január' => 1,
+ 'február' => 2,
+ 'március' => 3,
+ 'április' => 4,
+ 'május' => 5,
+ 'június' => 6,
+ 'július' => 7,
+ 'augusztus' => 8,
+ 'szeptember' => 9,
+ 'október' => 10,
+ 'november' => 11,
+ 'december' => 12,
+ // Greek
+ 'Ιαν' => 1,
+ 'Φεβ' => 2,
+ 'Μάώ' => 3,
+ 'Μαώ' => 3,
+ 'Απρ' => 4,
+ 'Μάι' => 5,
+ 'Μαϊ' => 5,
+ 'Μαι' => 5,
+ 'Ιούν' => 6,
+ 'Ιον' => 6,
+ 'Ιούλ' => 7,
+ 'Ιολ' => 7,
+ 'Αύγ' => 8,
+ 'Αυγ' => 8,
+ 'Σεπ' => 9,
+ 'Οκτ' => 10,
+ 'Νοέ' => 11,
+ 'Δεκ' => 12,
+ );
+
+ /**
+ * List of timezones, abbreviation => offset from UTC
+ *
+ * @access protected
+ * @var array
+ */
+ var $timezone = array(
+ 'ACDT' => 37800,
+ 'ACIT' => 28800,
+ 'ACST' => 34200,
+ 'ACT' => -18000,
+ 'ACWDT' => 35100,
+ 'ACWST' => 31500,
+ 'AEDT' => 39600,
+ 'AEST' => 36000,
+ 'AFT' => 16200,
+ 'AKDT' => -28800,
+ 'AKST' => -32400,
+ 'AMDT' => 18000,
+ 'AMT' => -14400,
+ 'ANAST' => 46800,
+ 'ANAT' => 43200,
+ 'ART' => -10800,
+ 'AZOST' => -3600,
+ 'AZST' => 18000,
+ 'AZT' => 14400,
+ 'BIOT' => 21600,
+ 'BIT' => -43200,
+ 'BOT' => -14400,
+ 'BRST' => -7200,
+ 'BRT' => -10800,
+ 'BST' => 3600,
+ 'BTT' => 21600,
+ 'CAST' => 18000,
+ 'CAT' => 7200,
+ 'CCT' => 23400,
+ 'CDT' => -18000,
+ 'CEDT' => 7200,
+ 'CET' => 3600,
+ 'CGST' => -7200,
+ 'CGT' => -10800,
+ 'CHADT' => 49500,
+ 'CHAST' => 45900,
+ 'CIST' => -28800,
+ 'CKT' => -36000,
+ 'CLDT' => -10800,
+ 'CLST' => -14400,
+ 'COT' => -18000,
+ 'CST' => -21600,
+ 'CVT' => -3600,
+ 'CXT' => 25200,
+ 'DAVT' => 25200,
+ 'DTAT' => 36000,
+ 'EADT' => -18000,
+ 'EAST' => -21600,
+ 'EAT' => 10800,
+ 'ECT' => -18000,
+ 'EDT' => -14400,
+ 'EEST' => 10800,
+ 'EET' => 7200,
+ 'EGT' => -3600,
+ 'EKST' => 21600,
+ 'EST' => -18000,
+ 'FJT' => 43200,
+ 'FKDT' => -10800,
+ 'FKST' => -14400,
+ 'FNT' => -7200,
+ 'GALT' => -21600,
+ 'GEDT' => 14400,
+ 'GEST' => 10800,
+ 'GFT' => -10800,
+ 'GILT' => 43200,
+ 'GIT' => -32400,
+ 'GST' => 14400,
+ 'GST' => -7200,
+ 'GYT' => -14400,
+ 'HAA' => -10800,
+ 'HAC' => -18000,
+ 'HADT' => -32400,
+ 'HAE' => -14400,
+ 'HAP' => -25200,
+ 'HAR' => -21600,
+ 'HAST' => -36000,
+ 'HAT' => -9000,
+ 'HAY' => -28800,
+ 'HKST' => 28800,
+ 'HMT' => 18000,
+ 'HNA' => -14400,
+ 'HNC' => -21600,
+ 'HNE' => -18000,
+ 'HNP' => -28800,
+ 'HNR' => -25200,
+ 'HNT' => -12600,
+ 'HNY' => -32400,
+ 'IRDT' => 16200,
+ 'IRKST' => 32400,
+ 'IRKT' => 28800,
+ 'IRST' => 12600,
+ 'JFDT' => -10800,
+ 'JFST' => -14400,
+ 'JST' => 32400,
+ 'KGST' => 21600,
+ 'KGT' => 18000,
+ 'KOST' => 39600,
+ 'KOVST' => 28800,
+ 'KOVT' => 25200,
+ 'KRAST' => 28800,
+ 'KRAT' => 25200,
+ 'KST' => 32400,
+ 'LHDT' => 39600,
+ 'LHST' => 37800,
+ 'LINT' => 50400,
+ 'LKT' => 21600,
+ 'MAGST' => 43200,
+ 'MAGT' => 39600,
+ 'MAWT' => 21600,
+ 'MDT' => -21600,
+ 'MESZ' => 7200,
+ 'MEZ' => 3600,
+ 'MHT' => 43200,
+ 'MIT' => -34200,
+ 'MNST' => 32400,
+ 'MSDT' => 14400,
+ 'MSST' => 10800,
+ 'MST' => -25200,
+ 'MUT' => 14400,
+ 'MVT' => 18000,
+ 'MYT' => 28800,
+ 'NCT' => 39600,
+ 'NDT' => -9000,
+ 'NFT' => 41400,
+ 'NMIT' => 36000,
+ 'NOVST' => 25200,
+ 'NOVT' => 21600,
+ 'NPT' => 20700,
+ 'NRT' => 43200,
+ 'NST' => -12600,
+ 'NUT' => -39600,
+ 'NZDT' => 46800,
+ 'NZST' => 43200,
+ 'OMSST' => 25200,
+ 'OMST' => 21600,
+ 'PDT' => -25200,
+ 'PET' => -18000,
+ 'PETST' => 46800,
+ 'PETT' => 43200,
+ 'PGT' => 36000,
+ 'PHOT' => 46800,
+ 'PHT' => 28800,
+ 'PKT' => 18000,
+ 'PMDT' => -7200,
+ 'PMST' => -10800,
+ 'PONT' => 39600,
+ 'PST' => -28800,
+ 'PWT' => 32400,
+ 'PYST' => -10800,
+ 'PYT' => -14400,
+ 'RET' => 14400,
+ 'ROTT' => -10800,
+ 'SAMST' => 18000,
+ 'SAMT' => 14400,
+ 'SAST' => 7200,
+ 'SBT' => 39600,
+ 'SCDT' => 46800,
+ 'SCST' => 43200,
+ 'SCT' => 14400,
+ 'SEST' => 3600,
+ 'SGT' => 28800,
+ 'SIT' => 28800,
+ 'SRT' => -10800,
+ 'SST' => -39600,
+ 'SYST' => 10800,
+ 'SYT' => 7200,
+ 'TFT' => 18000,
+ 'THAT' => -36000,
+ 'TJT' => 18000,
+ 'TKT' => -36000,
+ 'TMT' => 18000,
+ 'TOT' => 46800,
+ 'TPT' => 32400,
+ 'TRUT' => 36000,
+ 'TVT' => 43200,
+ 'TWT' => 28800,
+ 'UYST' => -7200,
+ 'UYT' => -10800,
+ 'UZT' => 18000,
+ 'VET' => -14400,
+ 'VLAST' => 39600,
+ 'VLAT' => 36000,
+ 'VOST' => 21600,
+ 'VUT' => 39600,
+ 'WAST' => 7200,
+ 'WAT' => 3600,
+ 'WDT' => 32400,
+ 'WEST' => 3600,
+ 'WFT' => 43200,
+ 'WIB' => 25200,
+ 'WIT' => 32400,
+ 'WITA' => 28800,
+ 'WKST' => 18000,
+ 'WST' => 28800,
+ 'YAKST' => 36000,
+ 'YAKT' => 32400,
+ 'YAPT' => 36000,
+ 'YEKST' => 21600,
+ 'YEKT' => 18000,
+ );
+
+ /**
+ * Cached PCRE for SimplePie_Parse_Date::$day
+ *
+ * @access protected
+ * @var string
+ */
+ var $day_pcre;
+
+ /**
+ * Cached PCRE for SimplePie_Parse_Date::$month
+ *
+ * @access protected
+ * @var string
+ */
+ var $month_pcre;
+
+ /**
+ * Array of user-added callback methods
+ *
+ * @access private
+ * @var array
+ */
+ var $built_in = array();
+
+ /**
+ * Array of user-added callback methods
+ *
+ * @access private
+ * @var array
+ */
+ var $user = array();
+
+ /**
+ * Create new SimplePie_Parse_Date object, and set self::day_pcre,
+ * self::month_pcre, and self::built_in
+ *
+ * @access private
+ */
+ function SimplePie_Parse_Date()
+ {
+ $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
+ $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
+
+ static $cache;
+ if (!isset($cache[get_class($this)]))
+ {
+ if (extension_loaded('Reflection'))
+ {
+ $class = new ReflectionClass(get_class($this));
+ $methods = $class->getMethods();
+ $all_methods = array();
+ foreach ($methods as $method)
+ {
+ $all_methods[] = $method->getName();
+ }
+ }
+ else
+ {
+ $all_methods = get_class_methods($this);
+ }
+
+ foreach ($all_methods as $method)
+ {
+ if (strtolower(substr($method, 0, 5)) === 'date_')
+ {
+ $cache[get_class($this)][] = $method;
+ }
+ }
+ }
+
+ foreach ($cache[get_class($this)] as $method)
+ {
+ $this->built_in[] = $method;
+ }
+ }
+
+ /**
+ * Get the object
+ *
+ * @access public
+ */
+ function get()
+ {
+ static $object;
+ if (!$object)
+ {
+ $object = new SimplePie_Parse_Date;
+ }
+ return $object;
+ }
+
+ /**
+ * Parse a date
+ *
+ * @final
+ * @access public
+ * @param string $date Date to parse
+ * @return int Timestamp corresponding to date string, or false on failure
+ */
+ function parse($date)
+ {
+ foreach ($this->user as $method)
+ {
+ if (($returned = call_user_func($method, $date)) !== false)
+ {
+ return $returned;
+ }
+ }
+
+ foreach ($this->built_in as $method)
+ {
+ if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
+ {
+ return $returned;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Add a callback method to parse a date
+ *
+ * @final
+ * @access public
+ * @param callback $callback
+ */
+ function add_callback($callback)
+ {
+ if (is_callable($callback))
+ {
+ $this->user[] = $callback;
+ }
+ else
+ {
+ trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
+ }
+ }
+
+ /**
+ * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
+ * well as allowing any of upper or lower case "T", horizontal tabs, or
+ * spaces to be used as the time seperator (including more than one))
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_w3cdtf($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $year = '([0-9]{4})';
+ $month = $day = $hour = $minute = $second = '([0-9]{2})';
+ $decimal = '([0-9]*)';
+ $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
+ $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
+ }
+ if (preg_match($pcre, $date, $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Year
+ 2: Month
+ 3: Day
+ 4: Hour
+ 5: Minute
+ 6: Second
+ 7: Decimal fraction of a second
+ 8: Zulu
+ 9: Timezone ±
+ 10: Timezone hours
+ 11: Timezone minutes
+ */
+
+ // Fill in empty matches
+ for ($i = count($match); $i <= 3; $i++)
+ {
+ $match[$i] = '1';
+ }
+
+ for ($i = count($match); $i <= 7; $i++)
+ {
+ $match[$i] = '0';
+ }
+
+ // Numeric timezone
+ if (isset($match[9]) && $match[9] !== '')
+ {
+ $timezone = $match[10] * 3600;
+ $timezone += $match[11] * 60;
+ if ($match[9] === '-')
+ {
+ $timezone = 0 - $timezone;
+ }
+ }
+ else
+ {
+ $timezone = 0;
+ }
+
+ // Convert the number of seconds to an integer, taking decimals into account
+ $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
+
+ return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Remove RFC822 comments
+ *
+ * @access protected
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ function remove_rfc2822_comments($string)
+ {
+ $string = (string) $string;
+ $position = 0;
+ $length = strlen($string);
+ $depth = 0;
+
+ $output = '';
+
+ while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
+ {
+ $output .= substr($string, $position, $pos - $position);
+ $position = $pos + 1;
+ if ($string[$pos - 1] !== '\\')
+ {
+ $depth++;
+ while ($depth && $position < $length)
+ {
+ $position += strcspn($string, '()', $position);
+ if ($string[$position - 1] === '\\')
+ {
+ $position++;
+ continue;
+ }
+ elseif (isset($string[$position]))
+ {
+ switch ($string[$position])
+ {
+ case '(':
+ $depth++;
+ break;
+
+ case ')':
+ $depth--;
+ break;
+ }
+ $position++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ $output .= '(';
+ }
+ }
+ $output .= substr($string, $position);
+
+ return $output;
+ }
+
+ /**
+ * Parse RFC2822's date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_rfc2822($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $wsp = '[\x09\x20]';
+ $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
+ $optional_fws = $fws . '?';
+ $day_name = $this->day_pcre;
+ $month = $this->month_pcre;
+ $day = '([0-9]{1,2})';
+ $hour = $minute = $second = '([0-9]{2})';
+ $year = '([0-9]{2,4})';
+ $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
+ $character_zone = '([A-Z]{1,5})';
+ $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
+ $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
+ }
+ if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Day name
+ 2: Day
+ 3: Month
+ 4: Year
+ 5: Hour
+ 6: Minute
+ 7: Second
+ 8: Timezone ±
+ 9: Timezone hours
+ 10: Timezone minutes
+ 11: Alphabetic timezone
+ */
+
+ // Find the month number
+ $month = $this->month[strtolower($match[3])];
+
+ // Numeric timezone
+ if ($match[8] !== '')
+ {
+ $timezone = $match[9] * 3600;
+ $timezone += $match[10] * 60;
+ if ($match[8] === '-')
+ {
+ $timezone = 0 - $timezone;
+ }
+ }
+ // Character timezone
+ elseif (isset($this->timezone[strtoupper($match[11])]))
+ {
+ $timezone = $this->timezone[strtoupper($match[11])];
+ }
+ // Assume everything else to be -0000
+ else
+ {
+ $timezone = 0;
+ }
+
+ // Deal with 2/3 digit years
+ if ($match[4] < 50)
+ {
+ $match[4] += 2000;
+ }
+ elseif ($match[4] < 1000)
+ {
+ $match[4] += 1900;
+ }
+
+ // Second is optional, if it is empty set it to zero
+ if ($match[7] !== '')
+ {
+ $second = $match[7];
+ }
+ else
+ {
+ $second = 0;
+ }
+
+ return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Parse RFC850's date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_rfc850($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $space = '[\x09\x20]+';
+ $day_name = $this->day_pcre;
+ $month = $this->month_pcre;
+ $day = '([0-9]{1,2})';
+ $year = $hour = $minute = $second = '([0-9]{2})';
+ $zone = '([A-Z]{1,5})';
+ $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
+ }
+ if (preg_match($pcre, $date, $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Day name
+ 2: Day
+ 3: Month
+ 4: Year
+ 5: Hour
+ 6: Minute
+ 7: Second
+ 8: Timezone
+ */
+
+ // Month
+ $month = $this->month[strtolower($match[3])];
+
+ // Character timezone
+ if (isset($this->timezone[strtoupper($match[8])]))
+ {
+ $timezone = $this->timezone[strtoupper($match[8])];
+ }
+ // Assume everything else to be -0000
+ else
+ {
+ $timezone = 0;
+ }
+
+ // Deal with 2 digit year
+ if ($match[4] < 50)
+ {
+ $match[4] += 2000;
+ }
+ else
+ {
+ $match[4] += 1900;
+ }
+
+ return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Parse C99's asctime()'s date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_asctime($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $space = '[\x09\x20]+';
+ $wday_name = $this->day_pcre;
+ $mon_name = $this->month_pcre;
+ $day = '([0-9]{1,2})';
+ $hour = $sec = $min = '([0-9]{2})';
+ $year = '([0-9]{4})';
+ $terminator = '\x0A?\x00?';
+ $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
+ }
+ if (preg_match($pcre, $date, $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Day name
+ 2: Month
+ 3: Day
+ 4: Hour
+ 5: Minute
+ 6: Second
+ 7: Year
+ */
+
+ $month = $this->month[strtolower($match[2])];
+ return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Parse dates using strtotime()
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_strtotime($date)
+ {
+ $strtotime = strtotime($date);
+ if ($strtotime === -1 || $strtotime === false)
+ {
+ return false;
+ }
+ else
+ {
+ return $strtotime;
+ }
+ }
+}
+
+/**
+ * Content-type sniffing
+ *
+ * @package SimplePie
+ */
+class SimplePie_Content_Type_Sniffer
+{
+ /**
+ * File object
+ *
+ * @var SimplePie_File
+ * @access private
+ */
+ var $file;
+
+ /**
+ * Create an instance of the class with the input file
+ *
+ * @access public
+ * @param SimplePie_Content_Type_Sniffer $file Input file
+ */
+ function SimplePie_Content_Type_Sniffer($file)
+ {
+ $this->file = $file;
+ }
+
+ /**
+ * Get the Content-Type of the specified file
+ *
+ * @access public
+ * @return string Actual Content-Type
+ */
+ function get_type()
+ {
+ if (isset($this->file->headers['content-type']))
+ {
+ if (!isset($this->file->headers['content-encoding'])
+ && ($this->file->headers['content-type'] === 'text/plain'
+ || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
+ || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
+ {
+ return $this->text_or_binary();
+ }
+
+ if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
+ {
+ $official = substr($this->file->headers['content-type'], 0, $pos);
+ }
+ else
+ {
+ $official = $this->file->headers['content-type'];
+ }
+ $official = strtolower($official);
+
+ if ($official === 'unknown/unknown'
+ || $official === 'application/unknown')
+ {
+ return $this->unknown();
+ }
+ elseif (substr($official, -4) === '+xml'
+ || $official === 'text/xml'
+ || $official === 'application/xml')
+ {
+ return $official;
+ }
+ elseif (substr($official, 0, 6) === 'image/')
+ {
+ if ($return = $this->image())
+ {
+ return $return;
+ }
+ else
+ {
+ return $official;
+ }
+ }
+ elseif ($official === 'text/html')
+ {
+ return $this->feed_or_html();
+ }
+ else
+ {
+ return $official;
+ }
+ }
+ else
+ {
+ return $this->unknown();
+ }
+ }
+
+ /**
+ * Sniff text or binary
+ *
+ * @access private
+ * @return string Actual Content-Type
+ */
+ function text_or_binary()
+ {
+ if (substr($this->file->body, 0, 2) === "\xFE\xFF"
+ || substr($this->file->body, 0, 2) === "\xFF\xFE"
+ || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
+ || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
+ {
+ return 'text/plain';
+ }
+ elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
+ {
+ return 'application/octect-stream';
+ }
+ else
+ {
+ return 'text/plain';
+ }
+ }
+
+ /**
+ * Sniff unknown
+ *
+ * @access private
+ * @return string Actual Content-Type
+ */
+ function unknown()
+ {
+ $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
+ if (strtolower(substr($this->file->body, $ws, 14)) === 'file->body, $ws, 5)) === 'file->body, $ws, 7)) === '
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/system/application/views/admin/.svn/text-base/dashboard.php.svn-base b/system/application/views/admin/.svn/text-base/dashboard.php.svn-base
new file mode 100644
index 0000000..d0327a7
--- /dev/null
+++ b/system/application/views/admin/.svn/text-base/dashboard.php.svn-base
@@ -0,0 +1,40 @@
+
\ No newline at end of file
diff --git a/system/application/views/admin/.svn/text-base/feed_add.php.svn-base b/system/application/views/admin/.svn/text-base/feed_add.php.svn-base
new file mode 100644
index 0000000..5c729a9
--- /dev/null
+++ b/system/application/views/admin/.svn/text-base/feed_add.php.svn-base
@@ -0,0 +1,27 @@
+
Not sure how to find a feed? Try simply putting the url of a webpage in the input box (e.g. http://twitter.com/yongfook) — it works 90% of the time!
+
\ No newline at end of file
diff --git a/system/application/views/admin/.svn/text-base/feeds.php.svn-base b/system/application/views/admin/.svn/text-base/feeds.php.svn-base
new file mode 100644
index 0000000..e6562fd
--- /dev/null
+++ b/system/application/views/admin/.svn/text-base/feeds.php.svn-base
@@ -0,0 +1,37 @@
+
\ No newline at end of file
diff --git a/system/application/views/admin/.svn/text-base/forgot.php.svn-base b/system/application/views/admin/.svn/text-base/forgot.php.svn-base
new file mode 100644
index 0000000..177d88e
--- /dev/null
+++ b/system/application/views/admin/.svn/text-base/forgot.php.svn-base
@@ -0,0 +1,32 @@
+
+
+
+
+ =$errors?>
+
+
+
+
+
+ Instructions have been sent to your email acount.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/system/application/views/admin/.svn/text-base/install.php.svn-base b/system/application/views/admin/.svn/text-base/install.php.svn-base
new file mode 100644
index 0000000..4ad2857
--- /dev/null
+++ b/system/application/views/admin/.svn/text-base/install.php.svn-base
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
Installation Successful! Your login details are below:
\ No newline at end of file
diff --git a/system/application/views/admin/.svn/text-base/items.php.svn-base b/system/application/views/admin/.svn/text-base/items.php.svn-base
new file mode 100644
index 0000000..1b7c5ea
--- /dev/null
+++ b/system/application/views/admin/.svn/text-base/items.php.svn-base
@@ -0,0 +1,97 @@
+
\ No newline at end of file
diff --git a/system/application/views/admin/.svn/text-base/login.php.svn-base b/system/application/views/admin/.svn/text-base/login.php.svn-base
new file mode 100644
index 0000000..296804b
--- /dev/null
+++ b/system/application/views/admin/.svn/text-base/login.php.svn-base
@@ -0,0 +1,31 @@
+
\ No newline at end of file
diff --git a/system/application/views/admin/.svn/text-base/options.php.svn-base b/system/application/views/admin/.svn/text-base/options.php.svn-base
new file mode 100644
index 0000000..59d82f7
--- /dev/null
+++ b/system/application/views/admin/.svn/text-base/options.php.svn-base
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
Remember! After you change any options, click the "Save Options" button at the bottom of the page.
+
+
\ No newline at end of file
diff --git a/system/application/views/admin/.svn/text-base/write.php.svn-base b/system/application/views/admin/.svn/text-base/write.php.svn-base
new file mode 100644
index 0000000..e01efaa
--- /dev/null
+++ b/system/application/views/admin/.svn/text-base/write.php.svn-base
@@ -0,0 +1,67 @@
+
Shorthand The blog post content area supports the Markdown method of shorthand markup.
+
+
\ No newline at end of file
diff --git a/system/application/views/admin/_activity_list.php b/system/application/views/admin/_activity_list.php
new file mode 100644
index 0000000..88dacfd
--- /dev/null
+++ b/system/application/views/admin/_activity_list.php
@@ -0,0 +1,38 @@
+
+
+
+
\ No newline at end of file
diff --git a/system/application/views/admin/dashboard.php b/system/application/views/admin/dashboard.php
new file mode 100644
index 0000000..d0327a7
--- /dev/null
+++ b/system/application/views/admin/dashboard.php
@@ -0,0 +1,40 @@
+
\ No newline at end of file
diff --git a/system/application/views/admin/feed_add.php b/system/application/views/admin/feed_add.php
new file mode 100644
index 0000000..5c729a9
--- /dev/null
+++ b/system/application/views/admin/feed_add.php
@@ -0,0 +1,27 @@
+
Not sure how to find a feed? Try simply putting the url of a webpage in the input box (e.g. http://twitter.com/yongfook) — it works 90% of the time!
+
\ No newline at end of file
diff --git a/system/application/views/admin/feeds.php b/system/application/views/admin/feeds.php
new file mode 100644
index 0000000..e6562fd
--- /dev/null
+++ b/system/application/views/admin/feeds.php
@@ -0,0 +1,37 @@
+
\ No newline at end of file
diff --git a/system/application/views/admin/forgot.php b/system/application/views/admin/forgot.php
new file mode 100644
index 0000000..177d88e
--- /dev/null
+++ b/system/application/views/admin/forgot.php
@@ -0,0 +1,32 @@
+
+
+
+
+ =$errors?>
+
+
+
+
+
+ Instructions have been sent to your email acount.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/system/application/views/admin/install.php b/system/application/views/admin/install.php
new file mode 100644
index 0000000..4ad2857
--- /dev/null
+++ b/system/application/views/admin/install.php
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
Installation Successful! Your login details are below:
\ No newline at end of file
diff --git a/system/application/views/admin/items.php b/system/application/views/admin/items.php
new file mode 100644
index 0000000..1b7c5ea
--- /dev/null
+++ b/system/application/views/admin/items.php
@@ -0,0 +1,97 @@
+
\ No newline at end of file
diff --git a/system/application/views/admin/login.php b/system/application/views/admin/login.php
new file mode 100644
index 0000000..296804b
--- /dev/null
+++ b/system/application/views/admin/login.php
@@ -0,0 +1,31 @@
+
\ No newline at end of file
diff --git a/system/application/views/admin/options.php b/system/application/views/admin/options.php
new file mode 100644
index 0000000..59d82f7
--- /dev/null
+++ b/system/application/views/admin/options.php
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
Remember! After you change any options, click the "Save Options" button at the bottom of the page.
+
+
\ No newline at end of file
diff --git a/system/application/views/admin/write.php b/system/application/views/admin/write.php
new file mode 100644
index 0000000..e01efaa
--- /dev/null
+++ b/system/application/views/admin/write.php
@@ -0,0 +1,67 @@
+
diff --git a/system/application/views/themes/boxy/.svn/text-base/_sidebar.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/_sidebar.php.svn-base
new file mode 100644
index 0000000..08fb3ea
--- /dev/null
+++ b/system/application/views/themes/boxy/.svn/text-base/_sidebar.php.svn-base
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ Blogs are evolving. You're looking at my Lifestream, a real-time flow of my activity across various websites, with the occasional blog post for nourishment.
+
\ No newline at end of file
diff --git a/system/application/views/themes/boxy/.svn/text-base/contact.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/contact.php.svn-base
new file mode 100644
index 0000000..65d32b7
--- /dev/null
+++ b/system/application/views/themes/boxy/.svn/text-base/contact.php.svn-base
@@ -0,0 +1,8 @@
+
+
+
+ I recommend www.wufoo.com to create a contact form and paste it here!
+
+
+ Your favourite external commenting service goes here! I recommend http://www.disqus.com
+
+
+
+load->view('themes/'.$this->config->item('theme').'/_sidebar')?>
\ No newline at end of file
diff --git a/system/application/views/themes/boxy/_activity_feed.php b/system/application/views/themes/boxy/_activity_feed.php
new file mode 100644
index 0000000..9dacd3b
--- /dev/null
+++ b/system/application/views/themes/boxy/_activity_feed.php
@@ -0,0 +1,77 @@
+
diff --git a/system/application/views/themes/boxy/_sidebar.php b/system/application/views/themes/boxy/_sidebar.php
new file mode 100644
index 0000000..08fb3ea
--- /dev/null
+++ b/system/application/views/themes/boxy/_sidebar.php
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ Blogs are evolving. You're looking at my Lifestream, a real-time flow of my activity across various websites, with the occasional blog post for nourishment.
+
\ No newline at end of file
diff --git a/system/application/views/themes/boxy/contact.php b/system/application/views/themes/boxy/contact.php
new file mode 100644
index 0000000..65d32b7
--- /dev/null
+++ b/system/application/views/themes/boxy/contact.php
@@ -0,0 +1,8 @@
+
+
+
+ I recommend www.wufoo.com to create a contact form and paste it here!
+
+
diff --git a/system/application/views/themes/sandbox/.svn/text-base/_sidebar.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/_sidebar.php.svn-base
new file mode 100644
index 0000000..85a3e61
--- /dev/null
+++ b/system/application/views/themes/sandbox/.svn/text-base/_sidebar.php.svn-base
@@ -0,0 +1,20 @@
+
+
+
+ Blogs are evolving. You're looking at my Lifestream, a real-time flow of my activity across various websites, with the occasional blog post for nourishment.
+
\ No newline at end of file
diff --git a/system/application/views/themes/sandbox/.svn/text-base/contact.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/contact.php.svn-base
new file mode 100644
index 0000000..884036f
--- /dev/null
+++ b/system/application/views/themes/sandbox/.svn/text-base/contact.php.svn-base
@@ -0,0 +1,8 @@
+
+
+
+ I recommend www.wufoo.com to create a contact form and paste it here!
+
+
+ Your favourite external commenting service goes here! I recommend http://www.disqus.com
+
+
+
+load->view('themes/'.$this->config->item('theme').'/_sidebar')?>
\ No newline at end of file
diff --git a/system/application/views/themes/sandbox/_activity_feed.php b/system/application/views/themes/sandbox/_activity_feed.php
new file mode 100644
index 0000000..1eaebaf
--- /dev/null
+++ b/system/application/views/themes/sandbox/_activity_feed.php
@@ -0,0 +1,52 @@
+
diff --git a/system/application/views/themes/sandbox/_sidebar.php b/system/application/views/themes/sandbox/_sidebar.php
new file mode 100644
index 0000000..85a3e61
--- /dev/null
+++ b/system/application/views/themes/sandbox/_sidebar.php
@@ -0,0 +1,20 @@
+
+
+
+ Blogs are evolving. You're looking at my Lifestream, a real-time flow of my activity across various websites, with the occasional blog post for nourishment.
+
\ No newline at end of file
diff --git a/system/application/views/themes/sandbox/contact.php b/system/application/views/themes/sandbox/contact.php
new file mode 100644
index 0000000..884036f
--- /dev/null
+++ b/system/application/views/themes/sandbox/contact.php
@@ -0,0 +1,8 @@
+
+
+
+ I recommend www.wufoo.com to create a contact form and paste it here!
+
+
+ Your favourite external commenting service goes here! I recommend http://www.disqus.com
+
+
+
+load->view('themes/'.$this->config->item('theme').'/_sidebar')?>
\ No newline at end of file
diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/_activity_feed.php b/system/application/views/themes/teh_blog_ar_(not)_dead/_activity_feed.php
new file mode 100755
index 0000000..8802ab7
--- /dev/null
+++ b/system/application/views/themes/teh_blog_ar_(not)_dead/_activity_feed.php
@@ -0,0 +1,138 @@
+
+
+
+
\ No newline at end of file
diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/_footer.php b/system/application/views/themes/teh_blog_ar_(not)_dead/_footer.php
new file mode 100755
index 0000000..3853344
--- /dev/null
+++ b/system/application/views/themes/teh_blog_ar_(not)_dead/_footer.php
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/_header.php b/system/application/views/themes/teh_blog_ar_(not)_dead/_header.php
new file mode 100755
index 0000000..b61887d
--- /dev/null
+++ b/system/application/views/themes/teh_blog_ar_(not)_dead/_header.php
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+ › config->item('lifestream_title')?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus in enim sed sapien semper venenatis. Nam tincidunt interdum ligula. Phasellus pretium lacus ut neque. Donec facilisis, dolor ac mattis congue, est pede consectetuer elit, in sodales diam augue in leo. Donec lectus erat, ultricies vitae, pretium sit amet, eleifend quis, sapien. Vestibulum diam. Quisque ullamcorper, metus sit amet pellentesque viverra, eros dui feugiat nunc, eu pretium tellus eros vel odio.
+
+
+
+
\ No newline at end of file
diff --git a/system/cache/index.html b/system/cache/index.html
new file mode 100755
index 0000000..5a1f5d6
--- /dev/null
+++ b/system/cache/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+403 Forbidden
+
+
+
+
+
+
Directory access is forbidden.
+
+
+
+
\ No newline at end of file
diff --git a/system/codeigniter/.svn/all-wcprops b/system/codeigniter/.svn/all-wcprops
new file mode 100644
index 0000000..873a52d
--- /dev/null
+++ b/system/codeigniter/.svn/all-wcprops
@@ -0,0 +1,41 @@
+K 25
+svn:wc:ra_dav:version-url
+V 41
+/svn/!svn/ver/18/trunk/system/codeigniter
+END
+CodeIgniter.php
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/svn/!svn/ver/18/trunk/system/codeigniter/CodeIgniter.php
+END
+Base4.php
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/svn/!svn/ver/18/trunk/system/codeigniter/Base4.php
+END
+Base5.php
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/svn/!svn/ver/18/trunk/system/codeigniter/Base5.php
+END
+Compat.php
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/svn/!svn/ver/18/trunk/system/codeigniter/Compat.php
+END
+index.html
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/svn/!svn/ver/18/trunk/system/codeigniter/index.html
+END
+Common.php
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/svn/!svn/ver/18/trunk/system/codeigniter/Common.php
+END
diff --git a/system/codeigniter/.svn/entries b/system/codeigniter/.svn/entries
new file mode 100644
index 0000000..5f427d4
--- /dev/null
+++ b/system/codeigniter/.svn/entries
@@ -0,0 +1,232 @@
+10
+
+dir
+124
+http://sweetcron.googlecode.com/svn/trunk/system/codeigniter
+http://sweetcron.googlecode.com/svn
+
+
+
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+51b50d7d-0b4b-0410-974b-f188aa86c7d9
+
+CodeIgniter.php
+file
+
+
+
+
+2009-09-15T00:18:19.000000Z
+2513d006ba799108d1bba5845de48a36
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7348
+
+Base4.php
+file
+
+
+
+
+2009-09-15T00:18:19.000000Z
+4bc28ba2e9466573429c37005e4ad640
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1865
+
+Base5.php
+file
+
+
+
+
+2009-09-15T00:18:19.000000Z
+5d6a54382fc049c11034540b019fa9a6
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1189
+
+Compat.php
+file
+
+
+
+
+2009-09-15T00:18:19.000000Z
+26b516b947ebf37654f137cf3c39b67b
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2179
+
+index.html
+file
+
+
+
+
+2009-09-15T00:18:19.000000Z
+362a648cc43551584abe596372cb8da8
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+149
+
+Common.php
+file
+
+
+
+
+2009-09-15T00:18:19.000000Z
+7c9fc2392e09880f7b33aa03622f44a7
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6809
+
diff --git a/system/codeigniter/.svn/prop-base/Base4.php.svn-base b/system/codeigniter/.svn/prop-base/Base4.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/codeigniter/.svn/prop-base/Base4.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/codeigniter/.svn/prop-base/Base5.php.svn-base b/system/codeigniter/.svn/prop-base/Base5.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/codeigniter/.svn/prop-base/Base5.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/codeigniter/.svn/prop-base/CodeIgniter.php.svn-base b/system/codeigniter/.svn/prop-base/CodeIgniter.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/codeigniter/.svn/prop-base/CodeIgniter.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/codeigniter/.svn/prop-base/Common.php.svn-base b/system/codeigniter/.svn/prop-base/Common.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/codeigniter/.svn/prop-base/Common.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/codeigniter/.svn/prop-base/Compat.php.svn-base b/system/codeigniter/.svn/prop-base/Compat.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/codeigniter/.svn/prop-base/Compat.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/codeigniter/.svn/prop-base/index.html.svn-base b/system/codeigniter/.svn/prop-base/index.html.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/codeigniter/.svn/prop-base/index.html.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/codeigniter/.svn/text-base/Base4.php.svn-base b/system/codeigniter/.svn/text-base/Base4.php.svn-base
new file mode 100644
index 0000000..577977c
--- /dev/null
+++ b/system/codeigniter/.svn/text-base/Base4.php.svn-base
@@ -0,0 +1,67 @@
+load->library('email') to instantiate
+ * classes that can then be used within controllers as $this->email->send()
+ *
+ * PHP 4 also has trouble referencing the CI super object within application
+ * constructors since objects do not exist until the class is fully
+ * instantiated. Basically PHP 4 sucks...
+ *
+ * Since PHP 5 doesn't suffer from this problem so we load one of
+ * two files based on the version of PHP being run.
+ *
+ * @package CodeIgniter
+ * @subpackage codeigniter
+ * @category front-controller
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/
+ */
+ class CI_Base extends CI_Loader {
+
+ function CI_Base()
+ {
+ // This allows syntax like $this->load->foo() to work
+ parent::CI_Loader();
+ $this->load =& $this;
+
+ // This allows resources used within controller constructors to work
+ global $OBJ;
+ $OBJ = $this->load; // Do NOT use a reference.
+ }
+}
+
+function &get_instance()
+{
+ global $CI, $OBJ;
+
+ if (is_object($CI))
+ {
+ return $CI;
+ }
+
+ return $OBJ->load;
+}
+
+?>
\ No newline at end of file
diff --git a/system/codeigniter/.svn/text-base/Base5.php.svn-base b/system/codeigniter/.svn/text-base/Base5.php.svn-base
new file mode 100644
index 0000000..c731a00
--- /dev/null
+++ b/system/codeigniter/.svn/text-base/Base5.php.svn-base
@@ -0,0 +1,54 @@
+
\ No newline at end of file
diff --git a/system/codeigniter/.svn/text-base/CodeIgniter.php.svn-base b/system/codeigniter/.svn/text-base/CodeIgniter.php.svn-base
new file mode 100644
index 0000000..8f9dbdf
--- /dev/null
+++ b/system/codeigniter/.svn/text-base/CodeIgniter.php.svn-base
@@ -0,0 +1,267 @@
+mark('total_execution_time_start');
+$BM->mark('loading_time_base_classes_start');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the hooks class
+ * ------------------------------------------------------
+ */
+
+$EXT =& load_class('Hooks');
+
+/*
+ * ------------------------------------------------------
+ * Is there a "pre_system" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('pre_system');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the base classes
+ * ------------------------------------------------------
+ */
+
+$CFG =& load_class('Config');
+$URI =& load_class('URI');
+$RTR =& load_class('Router');
+$OUT =& load_class('Output');
+
+/*
+ * ------------------------------------------------------
+ * Is there a valid cache file? If so, we're done...
+ * ------------------------------------------------------
+ */
+
+if ($EXT->_call_hook('cache_override') === FALSE)
+{
+ if ($OUT->_display_cache($CFG, $RTR) == TRUE)
+ {
+ exit;
+ }
+}
+
+/*
+ * ------------------------------------------------------
+ * Load the remaining base classes
+ * ------------------------------------------------------
+ */
+
+$IN =& load_class('Input');
+$LANG =& load_class('Language');
+
+/*
+ * ------------------------------------------------------
+ * Load the app controller and local controller
+ * ------------------------------------------------------
+ *
+ * Note: Due to the poor object handling in PHP 4 we'll
+ * conditionally load different versions of the base
+ * class. Retaining PHP 4 compatibility requires a bit of a hack.
+ *
+ * Note: The Loader class needs to be included first
+ *
+ */
+if (floor(phpversion()) < 5)
+{
+ load_class('Loader', FALSE);
+ require(BASEPATH.'codeigniter/Base4'.EXT);
+}
+else
+{
+ require(BASEPATH.'codeigniter/Base5'.EXT);
+}
+
+// Load the base controller class
+load_class('Controller', FALSE);
+
+// Load the local application controller
+// Note: The Router class automatically validates the controller path. If this include fails it
+// means that the default controller in the Routes.php file is not resolving to something valid.
+if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT))
+{
+ show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
+}
+
+include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT);
+
+// Set a mark point for benchmarking
+$BM->mark('loading_time_base_classes_end');
+
+
+/*
+ * ------------------------------------------------------
+ * Security check
+ * ------------------------------------------------------
+ *
+ * None of the functions in the app controller or the
+ * loader class can be called via the URI, nor can
+ * controller functions that begin with an underscore
+ */
+$class = $RTR->fetch_class();
+$method = $RTR->fetch_method();
+
+
+if ( ! class_exists($class)
+ OR $method == 'controller'
+ OR substr($method, 0, 1) == '_'
+ OR in_array($method, get_class_methods('Controller'), TRUE)
+ )
+{
+ show_404();
+}
+
+/*
+ * ------------------------------------------------------
+ * Is there a "pre_controller" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('pre_controller');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the controller and call requested method
+ * ------------------------------------------------------
+ */
+
+// Mark a start point so we can benchmark the controller
+$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
+
+$CI = new $class();
+
+// Is this a scaffolding request?
+if ($RTR->scaffolding_request === TRUE)
+{
+ if ($EXT->_call_hook('scaffolding_override') === FALSE)
+ {
+ $CI->_ci_scaffolding();
+ }
+}
+else
+{
+ /*
+ * ------------------------------------------------------
+ * Is there a "post_controller_constructor" hook?
+ * ------------------------------------------------------
+ */
+ $EXT->_call_hook('post_controller_constructor');
+
+ // Is there a "remap" function?
+ if (method_exists($CI, '_remap'))
+ {
+ $CI->_remap($method);
+ }
+ else
+ {
+ if ( ! method_exists($CI, $method))
+ {
+ show_404();
+ }
+
+ // Call the requested method.
+ // Any URI segments present (besides the class/function) will be passed to the method for convenience
+ call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
+ }
+}
+
+// Mark a benchmark end point
+$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
+
+/*
+ * ------------------------------------------------------
+ * Is there a "post_controller" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('post_controller');
+
+/*
+ * ------------------------------------------------------
+ * Send the final rendered output to the browser
+ * ------------------------------------------------------
+ */
+
+if ($EXT->_call_hook('display_override') === FALSE)
+{
+ $OUT->_display();
+}
+
+/*
+ * ------------------------------------------------------
+ * Is there a "post_system" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('post_system');
+
+/*
+ * ------------------------------------------------------
+ * Close the DB connection if one exists
+ * ------------------------------------------------------
+ */
+if (class_exists('CI_DB') AND isset($CI->db))
+{
+ $CI->db->close();
+}
+
+
+?>
\ No newline at end of file
diff --git a/system/codeigniter/.svn/text-base/Common.php.svn-base b/system/codeigniter/.svn/text-base/Common.php.svn-base
new file mode 100644
index 0000000..d9ddf80
--- /dev/null
+++ b/system/codeigniter/.svn/text-base/Common.php.svn-base
@@ -0,0 +1,298 @@
+show_error('An Error Was Encountered', $message);
+ exit;
+}
+
+
+/**
+* 404 Page Handler
+*
+* This function is similar to the show_error() function above
+* However, instead of the standard error template it displays
+* 404 errors.
+*
+* @access public
+* @return void
+*/
+function show_404($page = '')
+{
+ $error =& load_class('Exceptions');
+ $error->show_404($page);
+ exit;
+}
+
+
+/**
+* Error Logging Interface
+*
+* We use this as a simple mechanism to access the logging
+* class and send messages to be logged.
+*
+* @access public
+* @return void
+*/
+function log_message($level = 'error', $message, $php_error = FALSE)
+{
+ static $LOG;
+
+ $config =& get_config();
+ if ($config['log_threshold'] == 0)
+ {
+ return;
+ }
+
+ $LOG =& load_class('Log');
+ $LOG->write_log($level, $message, $php_error);
+}
+
+/**
+* Exception Handler
+*
+* This is the custom exception handler that is declaired at the top
+* of Codeigniter.php. The main reason we use this is permit
+* PHP errors to be logged in our own log files since we may
+* not have access to server logs. Since this function
+* effectively intercepts PHP errors, however, we also need
+* to display errors based on the current error_reporting level.
+* We do that with the use of a PHP error template.
+*
+* @access private
+* @return void
+*/
+function _exception_handler($severity, $message, $filepath, $line)
+{
+ // We don't bother with "strict" notices since they will fill up
+ // the log file with information that isn't normally very
+ // helpful. For example, if you are running PHP 5 and you
+ // use version 4 style class functions (without prefixes
+ // like "public", "private", etc.) you'll get notices telling
+ // you that these have been deprecated.
+
+ if ($severity == E_STRICT)
+ {
+ return;
+ }
+
+ $error =& load_class('Exceptions');
+
+ // Should we display the error?
+ // We'll get the current error_reporting level and add its bits
+ // with the severity bits to find out.
+
+ if (($severity & error_reporting()) == $severity)
+ {
+ $error->show_php_error($severity, $message, $filepath, $line);
+ }
+
+ // Should we log the error? No? We're done...
+ $config =& get_config();
+ if ($config['log_threshold'] == 0)
+ {
+ return;
+ }
+
+ $error->log_exception($severity, $message, $filepath, $line);
+}
+
+
+?>
\ No newline at end of file
diff --git a/system/codeigniter/.svn/text-base/Compat.php.svn-base b/system/codeigniter/.svn/text-base/Compat.php.svn-base
new file mode 100644
index 0000000..56ebbf4
--- /dev/null
+++ b/system/codeigniter/.svn/text-base/Compat.php.svn-base
@@ -0,0 +1,94 @@
+
\ No newline at end of file
diff --git a/system/codeigniter/.svn/text-base/index.html.svn-base b/system/codeigniter/.svn/text-base/index.html.svn-base
new file mode 100644
index 0000000..5a1f5d6
--- /dev/null
+++ b/system/codeigniter/.svn/text-base/index.html.svn-base
@@ -0,0 +1,15 @@
+
+
+
+
+403 Forbidden
+
+
+
+
+
+
Directory access is forbidden.
+
+
+
+
\ No newline at end of file
diff --git a/system/codeigniter/Base4.php b/system/codeigniter/Base4.php
new file mode 100755
index 0000000..577977c
--- /dev/null
+++ b/system/codeigniter/Base4.php
@@ -0,0 +1,67 @@
+load->library('email') to instantiate
+ * classes that can then be used within controllers as $this->email->send()
+ *
+ * PHP 4 also has trouble referencing the CI super object within application
+ * constructors since objects do not exist until the class is fully
+ * instantiated. Basically PHP 4 sucks...
+ *
+ * Since PHP 5 doesn't suffer from this problem so we load one of
+ * two files based on the version of PHP being run.
+ *
+ * @package CodeIgniter
+ * @subpackage codeigniter
+ * @category front-controller
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/
+ */
+ class CI_Base extends CI_Loader {
+
+ function CI_Base()
+ {
+ // This allows syntax like $this->load->foo() to work
+ parent::CI_Loader();
+ $this->load =& $this;
+
+ // This allows resources used within controller constructors to work
+ global $OBJ;
+ $OBJ = $this->load; // Do NOT use a reference.
+ }
+}
+
+function &get_instance()
+{
+ global $CI, $OBJ;
+
+ if (is_object($CI))
+ {
+ return $CI;
+ }
+
+ return $OBJ->load;
+}
+
+?>
\ No newline at end of file
diff --git a/system/codeigniter/Base5.php b/system/codeigniter/Base5.php
new file mode 100755
index 0000000..c731a00
--- /dev/null
+++ b/system/codeigniter/Base5.php
@@ -0,0 +1,54 @@
+
\ No newline at end of file
diff --git a/system/codeigniter/CodeIgniter.php b/system/codeigniter/CodeIgniter.php
new file mode 100755
index 0000000..8f9dbdf
--- /dev/null
+++ b/system/codeigniter/CodeIgniter.php
@@ -0,0 +1,267 @@
+mark('total_execution_time_start');
+$BM->mark('loading_time_base_classes_start');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the hooks class
+ * ------------------------------------------------------
+ */
+
+$EXT =& load_class('Hooks');
+
+/*
+ * ------------------------------------------------------
+ * Is there a "pre_system" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('pre_system');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the base classes
+ * ------------------------------------------------------
+ */
+
+$CFG =& load_class('Config');
+$URI =& load_class('URI');
+$RTR =& load_class('Router');
+$OUT =& load_class('Output');
+
+/*
+ * ------------------------------------------------------
+ * Is there a valid cache file? If so, we're done...
+ * ------------------------------------------------------
+ */
+
+if ($EXT->_call_hook('cache_override') === FALSE)
+{
+ if ($OUT->_display_cache($CFG, $RTR) == TRUE)
+ {
+ exit;
+ }
+}
+
+/*
+ * ------------------------------------------------------
+ * Load the remaining base classes
+ * ------------------------------------------------------
+ */
+
+$IN =& load_class('Input');
+$LANG =& load_class('Language');
+
+/*
+ * ------------------------------------------------------
+ * Load the app controller and local controller
+ * ------------------------------------------------------
+ *
+ * Note: Due to the poor object handling in PHP 4 we'll
+ * conditionally load different versions of the base
+ * class. Retaining PHP 4 compatibility requires a bit of a hack.
+ *
+ * Note: The Loader class needs to be included first
+ *
+ */
+if (floor(phpversion()) < 5)
+{
+ load_class('Loader', FALSE);
+ require(BASEPATH.'codeigniter/Base4'.EXT);
+}
+else
+{
+ require(BASEPATH.'codeigniter/Base5'.EXT);
+}
+
+// Load the base controller class
+load_class('Controller', FALSE);
+
+// Load the local application controller
+// Note: The Router class automatically validates the controller path. If this include fails it
+// means that the default controller in the Routes.php file is not resolving to something valid.
+if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT))
+{
+ show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
+}
+
+include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT);
+
+// Set a mark point for benchmarking
+$BM->mark('loading_time_base_classes_end');
+
+
+/*
+ * ------------------------------------------------------
+ * Security check
+ * ------------------------------------------------------
+ *
+ * None of the functions in the app controller or the
+ * loader class can be called via the URI, nor can
+ * controller functions that begin with an underscore
+ */
+$class = $RTR->fetch_class();
+$method = $RTR->fetch_method();
+
+
+if ( ! class_exists($class)
+ OR $method == 'controller'
+ OR substr($method, 0, 1) == '_'
+ OR in_array($method, get_class_methods('Controller'), TRUE)
+ )
+{
+ show_404();
+}
+
+/*
+ * ------------------------------------------------------
+ * Is there a "pre_controller" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('pre_controller');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the controller and call requested method
+ * ------------------------------------------------------
+ */
+
+// Mark a start point so we can benchmark the controller
+$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
+
+$CI = new $class();
+
+// Is this a scaffolding request?
+if ($RTR->scaffolding_request === TRUE)
+{
+ if ($EXT->_call_hook('scaffolding_override') === FALSE)
+ {
+ $CI->_ci_scaffolding();
+ }
+}
+else
+{
+ /*
+ * ------------------------------------------------------
+ * Is there a "post_controller_constructor" hook?
+ * ------------------------------------------------------
+ */
+ $EXT->_call_hook('post_controller_constructor');
+
+ // Is there a "remap" function?
+ if (method_exists($CI, '_remap'))
+ {
+ $CI->_remap($method);
+ }
+ else
+ {
+ if ( ! method_exists($CI, $method))
+ {
+ show_404();
+ }
+
+ // Call the requested method.
+ // Any URI segments present (besides the class/function) will be passed to the method for convenience
+ call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
+ }
+}
+
+// Mark a benchmark end point
+$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
+
+/*
+ * ------------------------------------------------------
+ * Is there a "post_controller" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('post_controller');
+
+/*
+ * ------------------------------------------------------
+ * Send the final rendered output to the browser
+ * ------------------------------------------------------
+ */
+
+if ($EXT->_call_hook('display_override') === FALSE)
+{
+ $OUT->_display();
+}
+
+/*
+ * ------------------------------------------------------
+ * Is there a "post_system" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('post_system');
+
+/*
+ * ------------------------------------------------------
+ * Close the DB connection if one exists
+ * ------------------------------------------------------
+ */
+if (class_exists('CI_DB') AND isset($CI->db))
+{
+ $CI->db->close();
+}
+
+
+?>
\ No newline at end of file
diff --git a/system/codeigniter/Common.php b/system/codeigniter/Common.php
new file mode 100755
index 0000000..d9ddf80
--- /dev/null
+++ b/system/codeigniter/Common.php
@@ -0,0 +1,298 @@
+show_error('An Error Was Encountered', $message);
+ exit;
+}
+
+
+/**
+* 404 Page Handler
+*
+* This function is similar to the show_error() function above
+* However, instead of the standard error template it displays
+* 404 errors.
+*
+* @access public
+* @return void
+*/
+function show_404($page = '')
+{
+ $error =& load_class('Exceptions');
+ $error->show_404($page);
+ exit;
+}
+
+
+/**
+* Error Logging Interface
+*
+* We use this as a simple mechanism to access the logging
+* class and send messages to be logged.
+*
+* @access public
+* @return void
+*/
+function log_message($level = 'error', $message, $php_error = FALSE)
+{
+ static $LOG;
+
+ $config =& get_config();
+ if ($config['log_threshold'] == 0)
+ {
+ return;
+ }
+
+ $LOG =& load_class('Log');
+ $LOG->write_log($level, $message, $php_error);
+}
+
+/**
+* Exception Handler
+*
+* This is the custom exception handler that is declaired at the top
+* of Codeigniter.php. The main reason we use this is permit
+* PHP errors to be logged in our own log files since we may
+* not have access to server logs. Since this function
+* effectively intercepts PHP errors, however, we also need
+* to display errors based on the current error_reporting level.
+* We do that with the use of a PHP error template.
+*
+* @access private
+* @return void
+*/
+function _exception_handler($severity, $message, $filepath, $line)
+{
+ // We don't bother with "strict" notices since they will fill up
+ // the log file with information that isn't normally very
+ // helpful. For example, if you are running PHP 5 and you
+ // use version 4 style class functions (without prefixes
+ // like "public", "private", etc.) you'll get notices telling
+ // you that these have been deprecated.
+
+ if ($severity == E_STRICT)
+ {
+ return;
+ }
+
+ $error =& load_class('Exceptions');
+
+ // Should we display the error?
+ // We'll get the current error_reporting level and add its bits
+ // with the severity bits to find out.
+
+ if (($severity & error_reporting()) == $severity)
+ {
+ $error->show_php_error($severity, $message, $filepath, $line);
+ }
+
+ // Should we log the error? No? We're done...
+ $config =& get_config();
+ if ($config['log_threshold'] == 0)
+ {
+ return;
+ }
+
+ $error->log_exception($severity, $message, $filepath, $line);
+}
+
+
+?>
\ No newline at end of file
diff --git a/system/codeigniter/Compat.php b/system/codeigniter/Compat.php
new file mode 100755
index 0000000..56ebbf4
--- /dev/null
+++ b/system/codeigniter/Compat.php
@@ -0,0 +1,94 @@
+
\ No newline at end of file
diff --git a/system/codeigniter/index.html b/system/codeigniter/index.html
new file mode 100755
index 0000000..5a1f5d6
--- /dev/null
+++ b/system/codeigniter/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+403 Forbidden
+
+
+
+
+
+
Directory access is forbidden.
+
+
+
+
\ No newline at end of file
diff --git a/system/database/.svn/all-wcprops b/system/database/.svn/all-wcprops
new file mode 100644
index 0000000..f0d3515
--- /dev/null
+++ b/system/database/.svn/all-wcprops
@@ -0,0 +1,53 @@
+K 25
+svn:wc:ra_dav:version-url
+V 38
+/svn/!svn/ver/18/trunk/system/database
+END
+DB_active_rec.php
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/svn/!svn/ver/18/trunk/system/database/DB_active_rec.php
+END
+DB_driver.php
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/svn/!svn/ver/18/trunk/system/database/DB_driver.php
+END
+DB_result.php
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/svn/!svn/ver/18/trunk/system/database/DB_result.php
+END
+index.html
+K 25
+svn:wc:ra_dav:version-url
+V 49
+/svn/!svn/ver/18/trunk/system/database/index.html
+END
+DB.php
+K 25
+svn:wc:ra_dav:version-url
+V 45
+/svn/!svn/ver/18/trunk/system/database/DB.php
+END
+DB_forge.php
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/svn/!svn/ver/18/trunk/system/database/DB_forge.php
+END
+DB_utility.php
+K 25
+svn:wc:ra_dav:version-url
+V 53
+/svn/!svn/ver/18/trunk/system/database/DB_utility.php
+END
+DB_cache.php
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/svn/!svn/ver/18/trunk/system/database/DB_cache.php
+END
diff --git a/system/database/.svn/entries b/system/database/.svn/entries
new file mode 100644
index 0000000..d1100dc
--- /dev/null
+++ b/system/database/.svn/entries
@@ -0,0 +1,303 @@
+10
+
+dir
+124
+http://sweetcron.googlecode.com/svn/trunk/system/database
+http://sweetcron.googlecode.com/svn
+
+
+
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+51b50d7d-0b4b-0410-974b-f188aa86c7d9
+
+DB_active_rec.php
+file
+
+
+
+
+2009-09-15T00:18:12.000000Z
+b97c0a58f575ac4b7e9b0c2231c63495
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+37746
+
+DB_driver.php
+file
+
+
+
+
+2009-09-15T00:18:12.000000Z
+55c956490502d6b6d29d84b235161430
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+26183
+
+DB_result.php
+file
+
+
+
+
+2009-09-15T00:18:12.000000Z
+2b5ad33038af076b66ab926c4b5b3681
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7680
+
+index.html
+file
+
+
+
+
+2009-09-15T00:18:12.000000Z
+362a648cc43551584abe596372cb8da8
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+149
+
+DB.php
+file
+
+
+
+
+2009-09-15T00:18:12.000000Z
+19444e375528319537ace1defee86523
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3362
+
+DB_forge.php
+file
+
+
+
+
+2009-09-15T00:18:12.000000Z
+120d33d09edfebd7f24c92ff7d3b55f1
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6835
+
+drivers
+dir
+
+DB_utility.php
+file
+
+
+
+
+2009-09-15T00:18:12.000000Z
+61562f8ee290f310ac9807fbdc3316be
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9560
+
+DB_cache.php
+file
+
+
+
+
+2009-09-15T00:18:12.000000Z
+2a0862afd5a08091a9d717bb4edad6da
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4326
+
diff --git a/system/database/.svn/prop-base/DB.php.svn-base b/system/database/.svn/prop-base/DB.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/database/.svn/prop-base/DB.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/database/.svn/prop-base/DB_active_rec.php.svn-base b/system/database/.svn/prop-base/DB_active_rec.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/database/.svn/prop-base/DB_active_rec.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/database/.svn/prop-base/DB_cache.php.svn-base b/system/database/.svn/prop-base/DB_cache.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/database/.svn/prop-base/DB_cache.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/database/.svn/prop-base/DB_driver.php.svn-base b/system/database/.svn/prop-base/DB_driver.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/database/.svn/prop-base/DB_driver.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/database/.svn/prop-base/DB_forge.php.svn-base b/system/database/.svn/prop-base/DB_forge.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/database/.svn/prop-base/DB_forge.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/database/.svn/prop-base/DB_result.php.svn-base b/system/database/.svn/prop-base/DB_result.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/database/.svn/prop-base/DB_result.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/database/.svn/prop-base/DB_utility.php.svn-base b/system/database/.svn/prop-base/DB_utility.php.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/database/.svn/prop-base/DB_utility.php.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/database/.svn/prop-base/index.html.svn-base b/system/database/.svn/prop-base/index.html.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/database/.svn/prop-base/index.html.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/database/.svn/text-base/DB.php.svn-base b/system/database/.svn/text-base/DB.php.svn-base
new file mode 100644
index 0000000..c3e7722
--- /dev/null
+++ b/system/database/.svn/text-base/DB.php.svn-base
@@ -0,0 +1,123 @@
+ $dns['scheme'],
+ 'hostname' => (isset($dns['host'])) ? rawurldecode($dns['host']) : '',
+ 'username' => (isset($dns['user'])) ? rawurldecode($dns['user']) : '',
+ 'password' => (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '',
+ 'database' => (isset($dns['path'])) ? rawurldecode(substr($dns['host'], 1)) : ''
+ );
+ }
+
+ // No DB specified yet? Beat them senseless...
+ if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')
+ {
+ show_error('You have not selected a database type to connect to.');
+ }
+
+ // Load the DB classes. Note: Since the active record class is optional
+ // we need to dynamically create a class that extends proper parent class
+ // based on whether we're using the active record class or not.
+ // Kudos to Paul for discovering this clever use of eval()
+
+ if ($active_record_override == TRUE)
+ {
+ $active_record = TRUE;
+ }
+
+ require_once(BASEPATH.'database/DB_driver'.EXT);
+
+ if (! isset($active_record) OR $active_record == TRUE)
+ {
+ require_once(BASEPATH.'database/DB_active_rec'.EXT);
+
+ if ( ! class_exists('CI_DB'))
+ {
+ eval('class CI_DB extends CI_DB_active_record { }');
+ }
+ }
+ else
+ {
+ if ( ! class_exists('CI_DB'))
+ {
+ eval('class CI_DB extends CI_DB_driver { }');
+ }
+ }
+
+ require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT);
+
+ // Instantiate the DB adapter
+ $driver = 'CI_DB_'.$params['dbdriver'].'_driver';
+ $DB =& new $driver($params);
+
+ if ($DB->autoinit == TRUE)
+ {
+ $DB->initialize();
+ }
+
+ return $DB;
+}
+
+
+?>
\ No newline at end of file
diff --git a/system/database/.svn/text-base/DB_active_rec.php.svn-base b/system/database/.svn/text-base/DB_active_rec.php.svn-base
new file mode 100644
index 0000000..263172a
--- /dev/null
+++ b/system/database/.svn/text-base/DB_active_rec.php.svn-base
@@ -0,0 +1,1733 @@
+display_error('db_table_name_required');
+ }
+
+ return $this->dbprefix.$table;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select
+ *
+ * Generates the SELECT portion of the query
+ *
+ * @access public
+ * @param string
+ * @return object
+ */
+ function select($select = '*', $protect_identifiers = TRUE)
+ {
+ if (is_string($select))
+ {
+ $select = explode(',', $select);
+ }
+
+ foreach ($select as $val)
+ {
+ $val = trim($val);
+
+ if ($val != '*' && $protect_identifiers !== FALSE)
+ {
+ if (strpos($val, '.') !== FALSE)
+ {
+ $val = $this->dbprefix.$val;
+ }
+ else
+ {
+ $val = $this->_protect_identifiers($val);
+ }
+ }
+
+ if ($val != '')
+ {
+ $this->ar_select[] = $val;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_select[] = $val;
+ }
+ }
+ }
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select Max
+ *
+ * Generates a SELECT MAX(field) portion of a query
+ *
+ * @access public
+ * @param string the field
+ * @param string an alias
+ * @return object
+ */
+ function select_max($select = '', $alias='')
+ {
+ if (!is_string($select) || $select == '')
+ {
+ $this->display_error('db_invalid_query');
+ }
+
+ $alias = ($alias != '') ? $alias : $select;
+
+ $sql = 'MAX('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias));
+
+ $this->ar_select[] = $sql;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_select[] = $sql;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select Min
+ *
+ * Generates a SELECT MIN(field) portion of a query
+ *
+ * @access public
+ * @param string the field
+ * @param string an alias
+ * @return object
+ */
+ function select_min($select = '', $alias='')
+ {
+ if (!is_string($select) || $select == '')
+ {
+ $this->display_error('db_invalid_query');
+ }
+
+ $alias = ($alias != '') ? $alias : $select;
+
+ $sql = 'MIN('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias));
+
+ $this->ar_select[] = $sql;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_select[] = $sql;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select Average
+ *
+ * Generates a SELECT AVG(field) portion of a query
+ *
+ * @access public
+ * @param string the field
+ * @param string an alias
+ * @return object
+ */
+ function select_avg($select = '', $alias='')
+ {
+ if (!is_string($select) || $select == '')
+ {
+ $this->display_error('db_invalid_query');
+ }
+
+ $alias = ($alias != '') ? $alias : $select;
+
+ $sql = 'AVG('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias));
+
+ $this->ar_select[] = $sql;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_select[] = $sql;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select Sum
+ *
+ * Generates a SELECT SUM(field) portion of a query
+ *
+ * @access public
+ * @param string the field
+ * @param string an alias
+ * @return object
+ */
+ function select_sum($select = '', $alias='')
+ {
+ if (!is_string($select) || $select == '')
+ {
+ $this->display_error('db_invalid_query');
+ }
+
+ $alias = ($alias != '') ? $alias : $select;
+
+ $sql = 'SUM('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias));
+
+ $this->ar_select[] = $sql;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_select[] = $sql;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * DISTINCT
+ *
+ * Sets a flag which tells the query string compiler to add DISTINCT
+ *
+ * @access public
+ * @param bool
+ * @return object
+ */
+ function distinct($val = TRUE)
+ {
+ $this->ar_distinct = (is_bool($val)) ? $val : TRUE;
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * From
+ *
+ * Generates the FROM portion of the query
+ *
+ * @access public
+ * @param mixed can be a string or array
+ * @return object
+ */
+ function from($from)
+ {
+ foreach ((array)$from as $val)
+ {
+ $this->ar_from[] = $this->_protect_identifiers($this->_track_aliases($val));
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_from[] = $this->_protect_identifiers($val);
+ }
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Join
+ *
+ * Generates the JOIN portion of the query
+ *
+ * @access public
+ * @param string
+ * @param string the join condition
+ * @param string the type of join
+ * @return object
+ */
+ function join($table, $cond, $type = '')
+ {
+ if ($type != '')
+ {
+ $type = strtoupper(trim($type));
+
+ if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE))
+ {
+ $type = '';
+ }
+ else
+ {
+ $type .= ' ';
+ }
+ }
+
+ // If a DB prefix is used we might need to add it to the column names
+ if ($this->dbprefix)
+ {
+ $this->_track_aliases($table);
+
+ // First we remove any existing prefixes in the condition to avoid duplicates
+ $cond = preg_replace('|('.$this->dbprefix.')([\w\.]+)([\W\s]+)|', "$2$3", $cond);
+
+ // Next we add the prefixes to the condition
+ $cond = preg_replace('|([\w\.]+)([\W\s]+)(.+)|', $this->dbprefix . "$1$2" . $this->dbprefix . "$3", $cond);
+ }
+
+ $join = $type.'JOIN '.$this->_protect_identifiers($this->dbprefix.$table, TRUE).' ON '.$cond;
+
+ $this->ar_join[] = $join;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_join[] = $join;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where
+ *
+ * Generates the WHERE portion of the query. Separates
+ * multiple calls with AND
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function where($key, $value = NULL, $escape = TRUE)
+ {
+ return $this->_where($key, $value, 'AND ', $escape);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * OR Where
+ *
+ * Generates the WHERE portion of the query. Separates
+ * multiple calls with OR
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function or_where($key, $value = NULL, $escape = TRUE)
+ {
+ return $this->_where($key, $value, 'OR ', $escape);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * orwhere() is an alias of or_where()
+ * this function is here for backwards compatibility, as
+ * orwhere() has been deprecated
+ */
+ function orwhere($key, $value = NULL, $escape = TRUE)
+ {
+ return $this->or_where($key, $value, $escape);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where
+ *
+ * Called by where() or orwhere()
+ *
+ * @access private
+ * @param mixed
+ * @param mixed
+ * @param string
+ * @return object
+ */
+ function _where($key, $value = NULL, $type = 'AND ', $escape = TRUE)
+ {
+ if ( ! is_array($key))
+ {
+ $key = array($key => $value);
+ }
+
+ foreach ($key as $k => $v)
+ {
+ $prefix = (count($this->ar_where) == 0) ? '' : $type;
+
+ if ( ! $this->_has_operator($k) && is_null($key[$k]))
+ {
+ // value appears not to have been set, assign the test to IS NULL
+ $k .= ' IS NULL';
+ }
+
+ if ( ! is_null($v))
+ {
+
+ if ($escape === TRUE)
+ {
+ // exception for "field<=" keys
+ if ($this->_has_operator($k))
+ {
+ $k = preg_replace("/([A-Za-z_0-9]+)/", $this->_protect_identifiers('$1'), $k);
+ }
+ else
+ {
+ $k = $this->_protect_identifiers($k);
+ }
+ }
+
+ if ( ! $this->_has_operator($k))
+ {
+ $k .= ' =';
+ }
+
+ $v = ' '.$this->escape($v);
+ }
+ else
+ {
+ $k = $this->_protect_identifiers($k, TRUE);
+ }
+
+ $this->ar_where[] = $prefix.$k.$v;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_where[] = $prefix.$k.$v;
+ }
+
+ }
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where_in
+ *
+ * Generates a WHERE field IN ('item', 'item') SQL query joined with
+ * AND if appropriate
+ *
+ * @access public
+ * @param string The field to search
+ * @param array The values searched on
+
+ * @return object
+ */
+ function where_in($key = NULL, $values = NULL)
+ {
+ return $this->_where_in($key, $values);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where_in_or
+ *
+ * Generates a WHERE field IN ('item', 'item') SQL query joined with
+ * OR if appropriate
+ *
+ * @access public
+ * @param string The field to search
+ * @param array The values searched on
+
+ * @return object
+ */
+ function or_where_in($key = NULL, $values = NULL)
+ {
+ return $this->_where_in($key, $values, FALSE, 'OR ');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where_not_in
+ *
+ * Generates a WHERE field NOT IN ('item', 'item') SQL query joined
+ * with AND if appropriate
+ *
+ * @access public
+ * @param string The field to search
+ * @param array The values searched on
+
+ * @return object
+ */
+ function where_not_in($key = NULL, $values = NULL)
+ {
+ return $this->_where_in($key, $values, TRUE);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where_not_in_or
+ *
+ * Generates a WHERE field NOT IN ('item', 'item') SQL query joined
+ * with OR if appropriate
+ *
+ * @access public
+ * @param string The field to search
+ * @param array The values searched on
+
+ * @return object
+ */
+ function or_where_not_in($key = NULL, $values = NULL)
+ {
+ return $this->_where_in($key, $values, FALSE, 'OR ');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where_in
+ *
+ * Called by where_in, where_in_or, where_not_in, where_not_in_or
+ *
+ * @access public
+ * @param string The field to search
+ * @param array The values searched on
+ * @param boolean If the statement whould be IN or NOT IN
+ * @param string
+ * @return object
+ */
+ function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ')
+ {
+ if ($key === NULL || !is_array($values))
+ {
+ return;
+ }
+
+ $not = ($not) ? ' NOT ' : '';
+
+ foreach ($values as $value)
+ {
+ $this->ar_wherein[] = $this->escape($value);
+ }
+
+ $prefix = (count($this->ar_where) == 0) ? '' : $type;
+
+ $where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") ";
+
+ $this->ar_where[] = $where_in;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_where[] = $where_in;
+ }
+
+ // reset the array for multiple calls
+ $this->ar_wherein = array();
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Like
+ *
+ * Generates a %LIKE% portion of the query. Separates
+ * multiple calls with AND
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function like($field, $match = '', $side = 'both')
+ {
+ return $this->_like($field, $match, 'AND ', $side);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Not Like
+ *
+ * Generates a NOT LIKE portion of the query. Separates
+ * multiple calls with AND
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function not_like($field, $match = '', $side = 'both')
+ {
+ return $this->_like($field, $match, 'AND ', $side, ' NOT');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * OR Like
+ *
+ * Generates a %LIKE% portion of the query. Separates
+ * multiple calls with OR
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function or_like($field, $match = '', $side = 'both')
+ {
+ return $this->_like($field, $match, 'OR ', $side);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * OR Not Like
+ *
+ * Generates a NOT LIKE portion of the query. Separates
+ * multiple calls with OR
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function or_not_like($field, $match = '', $side = 'both')
+ {
+ return $this->_like($field, $match, 'OR ', $side, 'NOT ');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * orlike() is an alias of or_like()
+ * this function is here for backwards compatibility, as
+ * orlike() has been deprecated
+ */
+ function orlike($field, $match = '', $side = 'both')
+ {
+ return $this->or_like($field, $match, $side);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Like
+ *
+ * Called by like() or orlike()
+ *
+ * @access private
+ * @param mixed
+ * @param mixed
+ * @param string
+ * @return object
+ */
+ function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '')
+ {
+ if ( ! is_array($field))
+ {
+ $field = array($field => $match);
+ }
+
+ foreach ($field as $k => $v)
+ {
+
+ $k = $this->_protect_identifiers($k);
+
+ $prefix = (count($this->ar_like) == 0) ? '' : $type;
+
+ $v = $this->escape_str($v);
+
+ if ($side == 'before')
+ {
+ $like_statement = $prefix." $k $not LIKE '%{$v}'";
+ }
+ elseif ($side == 'after')
+ {
+ $like_statement = $prefix." $k $not LIKE '{$v}%'";
+ }
+ else
+ {
+ $like_statement = $prefix." $k $not LIKE '%{$v}%'";
+ }
+
+ $this->ar_like[] = $like_statement;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_like[] = $like_statement;
+ }
+
+ }
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * GROUP BY
+ *
+ * @access public
+ * @param string
+ * @return object
+ */
+ function group_by($by)
+ {
+ if (is_string($by))
+ {
+ $by = explode(',', $by);
+ }
+
+ foreach ($by as $val)
+ {
+ $val = trim($val);
+
+ if ($val != '')
+ {
+ $this->ar_groupby[] = $this->_protect_identifiers($val);
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_groupby[] = $this->_protect_identifiers($val);
+ }
+ }
+ }
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * groupby() is an alias of group_by()
+ * this function is here for backwards compatibility, as
+ * groupby() has been deprecated
+ */
+ function groupby($by)
+ {
+ return $this->group_by($by);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the HAVING value
+ *
+ * Separates multiple calls with AND
+ *
+ * @access public
+ * @param string
+ * @param string
+ * @return object
+ */
+ function having($key, $value = '')
+ {
+ return $this->_having($key, $value, 'AND ');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the OR HAVING value
+ *
+ * Separates multiple calls with OR
+ *
+ * @access public
+ * @param string
+ * @param string
+ * @return object
+ */
+ function orhaving($key, $value = '')
+ {
+ return $this->_having($key, $value, 'OR ');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the HAVING values
+ *
+ * Called by having() or orhaving()
+ *
+ * @access private
+ * @param string
+
+ * @param string
+ * @return object
+ */
+ function _having($key, $value = '', $type = 'AND ')
+ {
+ if ( ! is_array($key))
+ {
+ $key = array($key => $value);
+ }
+
+ foreach ($key as $k => $v)
+ {
+ $prefix = (count($this->ar_having) == 0) ? '' : $type;
+ $k = $this->_protect_identifiers($k);
+
+ if ($v != '')
+ {
+ $v = ' '.$this->escape_str($v);
+ }
+
+ $this->ar_having[] = $prefix.$k.$v;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_having[] = $prefix.$k.$v;
+ }
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the ORDER BY value
+ *
+ * @access public
+ * @param string
+ * @param string direction: asc or desc
+ * @return object
+ */
+ function order_by($orderby, $direction = '')
+ {
+ if (strtolower($direction) == 'random')
+ {
+ $orderby = ''; // Random results want or don't need a field name
+ $direction = $this->_random_keyword;
+ }
+ elseif (trim($direction) != '')
+ {
+ $direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';
+ }
+
+ $orderby_statement = $this->_protect_identifiers($orderby, TRUE).$direction;
+
+ $this->ar_orderby[] = $orderby_statement;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_orderby[] = $orderby_statement;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * orderby() is an alias of order_by()
+ * this function is here for backwards compatibility, as
+ * orderby() has been deprecated
+ */
+ function orderby($orderby, $direction = '')
+ {
+ return $this->order_by($orderby, $direction);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the LIMIT value
+ *
+ * @access public
+ * @param integer the limit value
+ * @param integer the offset value
+ * @return object
+ */
+ function limit($value, $offset = '')
+ {
+ $this->ar_limit = $value;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_limit[] = $value;
+ }
+
+ if ($offset != '')
+ {
+ $this->ar_offset = $offset;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_offset[] = $offset;
+ }
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the OFFSET value
+ *
+ * @access public
+ * @param integer the offset value
+ * @return object
+ */
+ function offset($offset)
+ {
+ $this->ar_offset = $offset;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_offset[] = $offset;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * The "set" function. Allows key/value pairs to be set for inserting or updating
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param boolean
+ * @return object
+ */
+ function set($key, $value = '', $escape = TRUE)
+ {
+ $key = $this->_object_to_array($key);
+
+ if ( ! is_array($key))
+ {
+ $key = array($key => $value);
+ }
+
+ foreach ($key as $k => $v)
+ {
+ if ($escape === FALSE)
+ {
+ $this->ar_set[$this->_protect_identifiers($k)] = $v;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_offset[$this->_protect_identifiers($k)] = $v;
+ }
+ }
+ else
+ {
+ $this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v);
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_offset[$this->_protect_identifiers($k)] = $this->escape($v);
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get
+ *
+ * Compiles the select statement based on the other functions called
+ * and runs the query
+ *
+ * @access public
+ * @param string the table
+ * @param string the limit clause
+ * @param string the offset clause
+ * @return object
+ */
+ function get($table = '', $limit = null, $offset = null)
+ {
+ if ($table != '')
+ {
+ $this->_track_aliases($table);
+ $this->from($table);
+ }
+
+ if ( ! is_null($limit))
+ {
+ $this->limit($limit, $offset);
+ }
+
+ $sql = $this->_compile_select();
+
+ $result = $this->query($sql);
+ $this->_reset_select();
+ return $result;
+ }
+
+ /**
+ * "Count All Results" query
+ *
+ * Generates a platform-specific query string that counts all records
+ * returned by an Active Record query.
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+ function count_all_results($table = '')
+ {
+ if ($table != '')
+ {
+ $this->_track_aliases($table);
+ $this->from($table);
+ }
+
+ $sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows'));
+
+ $query = $this->query($sql);
+ $this->_reset_select();
+
+ if ($query->num_rows() == 0)
+ {
+ return '0';
+ }
+
+ $row = $query->row();
+ return $row->numrows;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get_Where
+ *
+ * Allows the where clause, limit and offset to be added directly
+ *
+ * @access public
+ * @param string the where clause
+ * @param string the limit clause
+ * @param string the offset clause
+ * @return object
+ */
+ function get_where($table = '', $where = null, $limit = null, $offset = null)
+ {
+ if ($table != '')
+ {
+ $this->_track_aliases($table);
+ $this->from($table);
+ }
+
+ if ( ! is_null($where))
+ {
+ $this->where($where);
+ }
+
+ if ( ! is_null($limit))
+ {
+ $this->limit($limit, $offset);
+ }
+
+ $sql = $this->_compile_select();
+
+ $result = $this->query($sql);
+ $this->_reset_select();
+ return $result;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * getwhere() is an alias of get_where()
+ * this function is here for backwards compatibility, as
+ * getwhere() has been deprecated
+ */
+ function getwhere($table = '', $where = null, $limit = null, $offset = null)
+ {
+ return $this->get_where($table, $where, $limit, $offset);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Insert
+ *
+ * Compiles an insert string and runs the query
+ *
+ * @access public
+ * @param string the table to retrieve the results from
+ * @param array an associative array of insert values
+ * @return object
+ */
+ function insert($table = '', $set = NULL)
+ {
+ if ( ! is_null($set))
+ {
+ $this->set($set);
+ }
+
+ if (count($this->ar_set) == 0)
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_use_set');
+ }
+ return FALSE;
+ }
+
+ if ($table == '')
+ {
+ if ( ! isset($this->ar_from[0]))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_set_table');
+ }
+ return FALSE;
+ }
+
+ $table = $this->ar_from[0];
+ }
+
+ $sql = $this->_insert($this->_protect_identifiers($this->dbprefix.$table), array_keys($this->ar_set), array_values($this->ar_set));
+
+ $this->_reset_write();
+ return $this->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Update
+ *
+ * Compiles an update string and runs the query
+ *
+ * @access public
+ * @param string the table to retrieve the results from
+ * @param array an associative array of update values
+ * @param mixed the where clause
+ * @return object
+ */
+ function update($table = '', $set = NULL, $where = NULL, $limit = NULL)
+ {
+ if ( ! is_null($set))
+ {
+ $this->set($set);
+ }
+
+ if (count($this->ar_set) == 0)
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_use_set');
+ }
+ return FALSE;
+ }
+
+ if ($table == '')
+ {
+ if ( ! isset($this->ar_from[0]))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_set_table');
+ }
+ return FALSE;
+ }
+
+ $table = $this->ar_from[0];
+ }
+
+ if ($where != NULL)
+ {
+ $this->where($where);
+ }
+
+ if ($limit != NULL)
+ {
+ $this->limit($limit);
+ }
+
+ $sql = $this->_update($this->_protect_identifiers($this->dbprefix.$table), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);
+
+ $this->_reset_write();
+ return $this->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Empty Table
+ *
+ * Compiles a delete string and runs "DELETE FROM table"
+ *
+ * @access public
+ * @param string the table to empty
+ * @return object
+ */
+ function empty_table($table = '')
+ {
+ if ($table == '')
+ {
+ if ( ! isset($this->ar_from[0]))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_set_table');
+ }
+ return FALSE;
+ }
+
+ $table = $this->ar_from[0];
+ }
+ else
+ {
+ $table = $this->_protect_identifiers($this->dbprefix.$table);
+ }
+
+
+ $sql = $this->_delete($table);
+
+ $this->_reset_write();
+
+ return $this->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Truncate
+ *
+ * Compiles a truncate string and runs the query
+ * If the database does not support the truncate() command
+ * This function maps to "DELETE FROM table"
+ *
+ * @access public
+ * @param string the table to truncate
+ * @return object
+ */
+ function truncate($table = '')
+ {
+ if ($table == '')
+ {
+ if ( ! isset($this->ar_from[0]))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_set_table');
+ }
+ return FALSE;
+ }
+
+ $table = $this->ar_from[0];
+ }
+ else
+ {
+ $table = $this->_protect_identifiers($this->dbprefix.$table);
+ }
+
+
+ $sql = $this->_truncate($table);
+
+ $this->_reset_write();
+
+ return $this->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete
+ *
+ * Compiles a delete string and runs the query
+ *
+ * @access public
+ * @param mixed the table(s) to delete from. String or array
+ * @param mixed the where clause
+ * @param mixed the limit clause
+ * @param boolean
+ * @return object
+ */
+ function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE)
+ {
+ if ($table == '')
+ {
+ if ( ! isset($this->ar_from[0]))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_set_table');
+ }
+ return FALSE;
+ }
+
+ $table = $this->ar_from[0];
+ }
+ elseif (is_array($table))
+ {
+ foreach($table as $single_table)
+ {
+ $this->delete($single_table, $where, $limit, FALSE);
+ }
+
+ $this->_reset_write();
+ return;
+ }
+ else
+ {
+ $table = $this->_protect_identifiers($this->dbprefix.$table);
+ }
+
+ if ($where != '')
+ {
+ $this->where($where);
+ }
+
+ if ($limit != NULL)
+ {
+ $this->limit($limit);
+ }
+
+ if (count($this->ar_where) == 0 && count($this->ar_like) == 0)
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_del_must_use_where');
+ }
+
+ return FALSE;
+ }
+
+ $sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit);
+
+ if ($reset_data)
+ {
+ $this->_reset_write();
+ }
+
+ return $this->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Use Table - DEPRECATED
+ *
+ * @deprecated use $this->db->from instead
+ */
+ function use_table($table)
+ {
+ return $this->from($table);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Tests whether the string has an SQL operator
+ *
+ * @access private
+ * @param string
+ * @return bool
+ */
+ function _has_operator($str)
+ {
+ $str = trim($str);
+ if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Track Aliases
+ *
+ * Used to track SQL statements written with aliased tables.
+ *
+ * @access private
+ * @param string The table to inspect
+ * @return string
+ */
+ function _track_aliases($table)
+ {
+ // if a table alias is used we can recognize it by a space
+ if (strpos($table, " ") !== FALSE)
+ {
+ // if the alias is written with the AS keyowrd, get it out
+ $table = preg_replace('/ AS /i', ' ', $table);
+
+ $this->ar_aliased_tables[] = trim(strrchr($table, " "));
+ }
+
+ return $this->dbprefix.$table;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Filter Table Aliases
+ *
+ * Intelligently removes database prefixes from aliased tables
+ *
+ * @access private
+ * @param array An array of compiled SQL
+ * @return array Cleaned up statement with aliases accounted for
+ */
+ function _filter_table_aliases($statements)
+ {
+ foreach ($statements as $k => $v)
+ {
+ foreach ($this->ar_aliased_tables as $table)
+ {
+ $statement = preg_replace('/(\w+\.\w+)/', $this->_protect_identifiers('$0'), $v); // makes `table.field`
+ $statement = str_replace(array($this->dbprefix.$table, '.'), array($table, $this->_protect_identifiers('.')), $statement);
+ }
+
+ $statements[$k] = $statement;
+ }
+
+ return $statements;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Compile the SELECT statement
+ *
+ * Generates a query string based on which functions were used.
+ * Should not be called directly. The get() function calls it.
+ *
+ * @access private
+ * @return string
+ */
+ function _compile_select($select_override = FALSE)
+ {
+ $this->_merge_cache();
+
+ $sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';
+
+ $sql .= (count($this->ar_select) == 0) ? '*' : implode(', ', $this->ar_select);
+
+ if ($select_override !== FALSE)
+ {
+ $sql = $select_override;
+ }
+
+ if (count($this->ar_from) > 0)
+ {
+ $sql .= "\nFROM ";
+ $sql .= $this->_from_tables($this->ar_from);
+ }
+
+ if (count($this->ar_join) > 0)
+ {
+ $sql .= "\n";
+
+ // special consideration for table aliases
+ if (count($this->ar_aliased_tables) > 0 && $this->dbprefix)
+ {
+ $sql .= implode("\n", $this->_filter_table_aliases($this->ar_join));
+ }
+ else
+ {
+ $sql .= implode("\n", $this->ar_join);
+ }
+
+ }
+
+ if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)
+ {
+ $sql .= "\nWHERE ";
+ }
+
+ $sql .= implode("\n", $this->ar_where);
+
+ if (count($this->ar_like) > 0)
+ {
+ if (count($this->ar_where) > 0)
+ {
+ $sql .= " AND ";
+ }
+
+ $sql .= implode("\n", $this->ar_like);
+ }
+
+ if (count($this->ar_groupby) > 0)
+ {
+
+ $sql .= "\nGROUP BY ";
+
+ // special consideration for table aliases
+ if (count($this->ar_aliased_tables) > 0 && $this->dbprefix)
+ {
+ $sql .= implode(", ", $this->_filter_table_aliases($this->ar_groupby));
+ }
+ else
+ {
+ $sql .= implode(', ', $this->ar_groupby);
+ }
+ }
+
+ if (count($this->ar_having) > 0)
+ {
+ $sql .= "\nHAVING ";
+ $sql .= implode("\n", $this->ar_having);
+ }
+
+ if (count($this->ar_orderby) > 0)
+ {
+ $sql .= "\nORDER BY ";
+ $sql .= implode(', ', $this->ar_orderby);
+
+ if ($this->ar_order !== FALSE)
+ {
+ $sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';
+ }
+ }
+
+ if (is_numeric($this->ar_limit))
+ {
+ $sql .= "\n";
+ $sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset);
+ }
+
+ return $sql;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Object to Array
+ *
+ * Takes an object as input and converts the class variables to array key/vals
+ *
+ * @access public
+ * @param object
+ * @return array
+ */
+ function _object_to_array($object)
+ {
+ if ( ! is_object($object))
+ {
+ return $object;
+ }
+
+ $array = array();
+ foreach (get_object_vars($object) as $key => $val)
+ {
+ // There are some built in keys we need to ignore for this conversion
+ if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name' && $key != '_ci_scaffolding' && $key != '_ci_scaff_table')
+
+ {
+ $array[$key] = $val;
+ }
+ }
+
+ return $array;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Start Cache
+ *
+ * Starts AR caching
+ *
+ * @access public
+ * @return void
+ */
+ function start_cache()
+ {
+ $this->ar_caching = TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Stop Cache
+ *
+ * Stops AR caching
+ *
+ * @access public
+ * @return void
+ */
+ function stop_cache()
+ {
+ $this->ar_caching = FALSE;
+ }
+
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Flush Cache
+ *
+ * Empties the AR cache
+ *
+ * @access public
+ * @return void
+ */
+ function flush_cache()
+ {
+ $ar_reset_items = array(
+ 'ar_cache_select' => array(),
+ 'ar_cache_from' => array(),
+ 'ar_cache_join' => array(),
+ 'ar_cache_where' => array(),
+ 'ar_cache_like' => array(),
+ 'ar_cache_groupby' => array(),
+ 'ar_cache_having' =>array(),
+ 'ar_cache_orderby' => array(),
+ 'ar_cache_set' => array()
+ );
+
+ $this->_reset_run($ar_reset_items);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Merge Cache
+ *
+ * When called, this function merges any cached AR arrays with
+ * locally called ones.
+ *
+ * @access private
+ * @return void
+ */
+ function _merge_cache()
+ {
+ $ar_items = array('select', 'from', 'join', 'where', 'like', 'groupby', 'having', 'orderby', 'set');
+
+ foreach ($ar_items as $ar_item)
+ {
+ $ar_cache_item = 'ar_cache_'.$ar_item;
+ $ar_item = 'ar_'.$ar_item;
+ $this->$ar_item = array_unique(array_merge($this->$ar_item, $this->$ar_cache_item));
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Resets the active record values. Called by the get() function
+ *
+ * @access private
+ * @param array An array of fields to reset
+ * @return void
+ */
+ function _reset_run($ar_reset_items)
+ {
+ foreach ($ar_reset_items as $item => $default_value)
+ {
+ if (!in_array($item, $this->ar_store_array))
+ {
+ $this->$item = $default_value;
+ }
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Resets the active record values. Called by the get() function
+ *
+ * @access private
+ * @return void
+ */
+ function _reset_select()
+ {
+ $ar_reset_items = array(
+ 'ar_select' => array(),
+ 'ar_from' => array(),
+ 'ar_join' => array(),
+ 'ar_where' => array(),
+ 'ar_like' => array(),
+ 'ar_groupby' => array(),
+ 'ar_having' => array(),
+ 'ar_orderby' => array(),
+ 'ar_wherein' => array(),
+ 'ar_aliased_tables' => array(),
+ 'ar_distinct' => FALSE,
+ 'ar_limit' => FALSE,
+ 'ar_offset' => FALSE,
+ 'ar_order' => FALSE,
+ );
+
+ $this->_reset_run($ar_reset_items);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Resets the active record "write" values.
+ *
+ * Called by the insert() update() and delete() functions
+ *
+ * @access private
+ * @return void
+ */
+ function _reset_write()
+ {
+ $ar_reset_items = array(
+ 'ar_set' => array(),
+ 'ar_from' => array(),
+ 'ar_where' => array(),
+ 'ar_like' => array(),
+ 'ar_orderby' => array(),
+ 'ar_limit' => FALSE,
+ 'ar_order' => FALSE
+ );
+
+ $this->_reset_run($ar_reset_items);
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/system/database/.svn/text-base/DB_cache.php.svn-base b/system/database/.svn/text-base/DB_cache.php.svn-base
new file mode 100644
index 0000000..ad54fc3
--- /dev/null
+++ b/system/database/.svn/text-base/DB_cache.php.svn-base
@@ -0,0 +1,189 @@
+CI
+ // and load the file helper since we use it a lot
+ $this->CI =& get_instance();
+ $this->CI->load->helper('file');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set Cache Directory Path
+ *
+ * @access public
+ * @param string the path to the cache directory
+ * @return bool
+ */
+ function check_path($path = '')
+ {
+ if ($path == '')
+ {
+ if ($this->CI->db->cachedir == '')
+ {
+ return $this->CI->db->cache_off();
+ }
+
+ $path = $this->CI->db->cachedir;
+ }
+
+ // Add a trailing slash to the path if needed
+ $path = preg_replace("/(.+?)\/*$/", "\\1/", $path);
+
+ if ( ! is_dir($path) OR ! is_really_writable($path))
+ {
+ // If the path is wrong we'll turn off caching
+ return $this->CI->db->cache_off();
+ }
+
+ $this->CI->db->cachedir = $path;
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Retrieve a cached query
+ *
+ * The URI being requested will become the name of the cache sub-folder.
+ * An MD5 hash of the SQL statement will become the cache file name
+ *
+ * @access public
+ * @return string
+ */
+ function read($sql)
+ {
+ if ( ! $this->check_path())
+ {
+ return $this->CI->db->cache_off();
+ }
+
+ $uri = ($this->CI->uri->segment(1) == FALSE) ? 'default.' : $this->CI->uri->segment(1).'+';
+ $uri .= ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
+
+ $filepath = $uri.'/'.md5($sql);
+
+ if (FALSE === ($cachedata = read_file($this->CI->db->cachedir.$filepath)))
+ {
+ return FALSE;
+ }
+
+ return unserialize($cachedata);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Write a query to a cache file
+ *
+ * @access public
+ * @return bool
+ */
+ function write($sql, $object)
+ {
+ if ( ! $this->check_path())
+ {
+ return $this->CI->db->cache_off();
+ }
+
+ $uri = ($this->CI->uri->segment(1) == FALSE) ? 'default.' : $this->CI->uri->segment(1).'+';
+ $uri .= ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
+
+ $dir_path = $this->CI->db->cachedir.$uri.'/';
+
+ $filename = md5($sql);
+
+ if ( ! @is_dir($dir_path))
+ {
+ if ( ! @mkdir($dir_path, 0777))
+ {
+ return FALSE;
+ }
+
+ @chmod($dir_path, 0777);
+ }
+
+ if (write_file($dir_path.$filename, serialize($object)) === FALSE)
+ {
+ return FALSE;
+ }
+
+ @chmod($dir_path.$filename, 0777);
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete cache files within a particular directory
+ *
+ * @access public
+ * @return bool
+ */
+ function delete($segment_one = '', $segment_two = '')
+ {
+ if ($segment_one == '')
+ {
+ $segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
+ }
+
+ if ($segment_two == '')
+ {
+ $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
+ }
+
+ $dir_path = $this->CI->db->cachedir.$segment_one.'+'.$segment_two.'/';
+
+ delete_files($dir_path, TRUE);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete all existing cache files
+ *
+ * @access public
+ * @return bool
+ */
+ function delete_all()
+ {
+ delete_files($this->CI->db->cachedir, TRUE);
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/system/database/.svn/text-base/DB_driver.php.svn-base b/system/database/.svn/text-base/DB_driver.php.svn-base
new file mode 100644
index 0000000..b101317
--- /dev/null
+++ b/system/database/.svn/text-base/DB_driver.php.svn-base
@@ -0,0 +1,1148 @@
+ $val)
+ {
+ $this->$key = $val;
+ }
+ }
+
+ log_message('debug', 'Database Driver Class Initialized');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Initialize Database Settings
+ *
+ * @access private Called by the constructor
+ * @param mixed
+ * @return void
+ */
+ function initialize($create_db = FALSE)
+ {
+ // If an existing DB connection resource is supplied
+ // there is no need to connect and select the database
+ if (is_resource($this->conn_id))
+ {
+ return TRUE;
+ }
+
+ // Connect to the database
+ $this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect();
+
+ // No connection? Throw an error
+ if ( ! $this->conn_id)
+ {
+ log_message('error', 'Unable to connect to the database');
+
+ if ($this->db_debug)
+ {
+ $this->display_error('db_unable_to_connect');
+ }
+ return FALSE;
+ }
+
+ // Select the database
+ if ($this->database != '')
+ {
+ if ( ! $this->db_select())
+ {
+ // Should we attempt to create the database?
+ if ($create_db == TRUE)
+ {
+ // Load the DB utility class
+ $CI =& get_instance();
+ $CI->load->dbutil();
+
+ // Create the DB
+ if ( ! $CI->dbutil->create_database($this->database))
+ {
+ log_message('error', 'Unable to create database: '.$this->database);
+
+ if ($this->db_debug)
+ {
+ $this->display_error('db_unable_to_create', $this->database);
+ }
+ return FALSE;
+ }
+ else
+ {
+ // In the event the DB was created we need to select it
+ if ($this->db_select())
+ {
+ if (! $this->db_set_charset($this->char_set, $this->dbcollat))
+ {
+ log_message('error', 'Unable to set database connection charset: '.$this->char_set);
+
+ if ($this->db_debug)
+ {
+ $this->display_error('db_unable_to_set_charset', $this->char_set);
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ }
+ }
+
+ log_message('error', 'Unable to select database: '.$this->database);
+
+ if ($this->db_debug)
+ {
+ $this->display_error('db_unable_to_select', $this->database);
+ }
+ return FALSE;
+ }
+
+ if (! $this->db_set_charset($this->char_set, $this->dbcollat))
+ {
+ log_message('error', 'Unable to set database connection charset: '.$this->char_set);
+
+ if ($this->db_debug)
+ {
+ $this->display_error('db_unable_to_set_charset', $this->char_set);
+ }
+
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * The name of the platform in use (mysql, mssql, etc...)
+ *
+ * @access public
+ * @return string
+ */
+ function platform()
+ {
+ return $this->dbdriver;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Database Version Number. Returns a string containing the
+ * version of the database being used
+ *
+ * @access public
+ * @return string
+ */
+ function version()
+ {
+ if (FALSE === ($sql = $this->_version()))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_unsupported_function');
+ }
+ return FALSE;
+ }
+
+ if ($this->dbdriver == 'oci8')
+ {
+ return $sql;
+ }
+
+ $query = $this->query($sql);
+ return $query->row('ver');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Execute the query
+ *
+ * Accepts an SQL string as input and returns a result object upon
+ * successful execution of a "read" type query. Returns boolean TRUE
+ * upon successful execution of a "write" type query. Returns boolean
+ * FALSE upon failure, and if the $db_debug variable is set to TRUE
+ * will raise an error.
+ *
+ * @access public
+ * @param string An SQL query string
+ * @param array An array of binding data
+ * @return mixed
+ */
+ function query($sql, $binds = FALSE, $return_object = TRUE)
+ {
+ if ($sql == '')
+ {
+ if ($this->db_debug)
+ {
+ log_message('error', 'Invalid query: '.$sql);
+ return $this->display_error('db_invalid_query');
+ }
+ return FALSE;
+ }
+
+ // Verify table prefix and replace if necessary
+ if ( ($this->dbprefix != '' AND $this->swap_pre != '') AND ($this->dbprefix != $this->swap_pre) )
+ {
+ $sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql);
+ }
+
+ // Is query caching enabled? If the query is a "read type"
+ // we will load the caching class and return the previously
+ // cached query if it exists
+ if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))
+ {
+ if ($this->_cache_init())
+ {
+ $this->load_rdriver();
+ if (FALSE !== ($cache = $this->CACHE->read($sql)))
+ {
+ return $cache;
+ }
+ }
+ }
+
+ // Compile binds if needed
+ if ($binds !== FALSE)
+ {
+ $sql = $this->compile_binds($sql, $binds);
+ }
+
+ // Save the query for debugging
+ if ($this->save_queries == TRUE)
+ {
+ $this->queries[] = $sql;
+ }
+
+ // Start the Query Timer
+ $time_start = list($sm, $ss) = explode(' ', microtime());
+
+ // Run the Query
+ if (FALSE === ($this->result_id = $this->simple_query($sql)))
+ {
+ // This will trigger a rollback if transactions are being used
+ $this->_trans_status = FALSE;
+
+ if ($this->db_debug)
+ {
+ log_message('error', 'Query error: '.$this->_error_message());
+ return $this->display_error(
+ array(
+ 'Error Number: '.$this->_error_number(),
+ $this->_error_message(),
+ $sql
+ )
+ );
+ }
+
+ return FALSE;
+ }
+
+ // Stop and aggregate the query time results
+ $time_end = list($em, $es) = explode(' ', microtime());
+ $this->benchmark += ($em + $es) - ($sm + $ss);
+
+ if ($this->save_queries == TRUE)
+ {
+ $this->query_times[] = ($em + $es) - ($sm + $ss);
+ }
+
+ // Increment the query counter
+ $this->query_count++;
+
+ // Was the query a "write" type?
+ // If so we'll simply return true
+ if ($this->is_write_type($sql) === TRUE)
+ {
+ // If caching is enabled we'll auto-cleanup any
+ // existing files related to this particular URI
+ if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())
+ {
+ $this->CACHE->delete();
+ }
+
+ return TRUE;
+ }
+
+ // Return TRUE if we don't need to create a result object
+ // Currently only the Oracle driver uses this when stored
+ // procedures are used
+ if ($return_object !== TRUE)
+ {
+ return TRUE;
+ }
+
+ // Load and instantiate the result driver
+
+ $driver = $this->load_rdriver();
+ $RES = new $driver();
+ $RES->conn_id = $this->conn_id;
+ $RES->result_id = $this->result_id;
+ $RES->num_rows = $RES->num_rows();
+
+ if ($this->dbdriver == 'oci8')
+ {
+ $RES->stmt_id = $this->stmt_id;
+ $RES->curs_id = NULL;
+ $RES->limit_used = $this->limit_used;
+ }
+
+ // Is query caching enabled? If so, we'll serialize the
+ // result object and save it to a cache file.
+ if ($this->cache_on == TRUE AND $this->_cache_init())
+ {
+ // We'll create a new instance of the result object
+ // only without the platform specific driver since
+ // we can't use it with cached data (the query result
+ // resource ID won't be any good once we've cached the
+ // result object, so we'll have to compile the data
+ // and save it)
+ $CR = new CI_DB_result();
+ $CR->num_rows = $RES->num_rows();
+ $CR->result_object = $RES->result_object();
+ $CR->result_array = $RES->result_array();
+
+ // Reset these since cached objects can not utilize resource IDs.
+ $CR->conn_id = NULL;
+ $CR->result_id = NULL;
+
+ $this->CACHE->write($sql, $CR);
+ }
+
+ return $RES;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Load the result drivers
+ *
+ * @access public
+ * @return string the name of the result class
+ */
+ function load_rdriver()
+ {
+ $driver = 'CI_DB_'.$this->dbdriver.'_result';
+
+ if ( ! class_exists($driver))
+ {
+ include_once(BASEPATH.'database/DB_result'.EXT);
+ include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT);
+ }
+
+ return $driver;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Simple Query
+ * This is a simplified version of the query() function. Internally
+ * we only use it when running transaction commands since they do
+ * not require all the features of the main query() function.
+ *
+ * @access public
+ * @param string the sql query
+ * @return mixed
+ */
+ function simple_query($sql)
+ {
+ if ( ! $this->conn_id)
+ {
+ $this->initialize();
+ }
+
+ return $this->_execute($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Disable Transactions
+ * This permits transactions to be disabled at run-time.
+ *
+ * @access public
+ * @return void
+ */
+ function trans_off()
+ {
+ $this->trans_enabled = FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Start Transaction
+ *
+ * @access public
+ * @return void
+ */
+ function trans_start($test_mode = FALSE)
+ {
+ if ( ! $this->trans_enabled)
+ {
+ return FALSE;
+ }
+
+ // When transactions are nested we only begin/commit/rollback the outermost ones
+ if ($this->_trans_depth > 0)
+ {
+ $this->_trans_depth += 1;
+ return;
+ }
+
+ $this->trans_begin($test_mode);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Complete Transaction
+ *
+ * @access public
+ * @return bool
+ */
+ function trans_complete()
+ {
+ if ( ! $this->trans_enabled)
+ {
+ return FALSE;
+ }
+
+ // When transactions are nested we only begin/commit/rollback the outermost ones
+ if ($this->_trans_depth > 1)
+ {
+ $this->_trans_depth -= 1;
+ return TRUE;
+ }
+
+ // The query() function will set this flag to TRUE in the event that a query failed
+ if ($this->_trans_status === FALSE)
+ {
+ $this->trans_rollback();
+
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_transaction_failure');
+ }
+ return FALSE;
+ }
+
+ $this->trans_commit();
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Lets you retrieve the transaction flag to determine if it has failed
+ *
+ * @access public
+ * @return bool
+ */
+ function trans_status()
+ {
+ return $this->_trans_status;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Compile Bindings
+ *
+ * @access public
+ * @param string the sql statement
+ * @param array an array of bind data
+ * @return string
+ */
+ function compile_binds($sql, $binds)
+ {
+ if (strpos($sql, $this->bind_marker) === FALSE)
+ {
+ return $sql;
+ }
+
+ if ( ! is_array($binds))
+ {
+ $binds = array($binds);
+ }
+
+ // Get the sql segments around the bind markers
+ $segments = explode($this->bind_marker, $sql);
+
+ // The count of bind should be 1 less then the count of segments
+ // If there are more bind arguments trim it down
+ if (count($binds) >= count($segments)) {
+ $binds = array_slice($binds, 0, count($segments)-1);
+ }
+
+ // Construct the binded query
+ $result = $segments[0];
+ $i = 0;
+ foreach ($binds as $bind)
+ {
+ $result .= $this->escape($bind);
+ $result .= $segments[++$i];
+ }
+
+ return $result;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Determines if a query is a "write" type.
+ *
+ * @access public
+ * @param string An SQL query string
+ * @return boolean
+ */
+ function is_write_type($sql)
+ {
+ if ( ! preg_match('/^\s*"?(INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql))
+ {
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Calculate the aggregate query elapsed time
+ *
+ * @access public
+ * @param integer The number of decimal places
+ * @return integer
+ */
+ function elapsed_time($decimals = 6)
+ {
+ return number_format($this->benchmark, $decimals);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the total number of queries
+ *
+ * @access public
+ * @return integer
+ */
+ function total_queries()
+ {
+ return $this->query_count;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the last query that was executed
+ *
+ * @access public
+ * @return void
+ */
+ function last_query()
+ {
+ return end($this->queries);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Protect Identifiers
+ *
+ * This function adds backticks if appropriate based on db type
+ *
+ * @access private
+ * @param mixed the item to escape
+ * @param boolean only affect the first word
+ * @return mixed the item with backticks
+ */
+ function protect_identifiers($item, $first_word_only = FALSE)
+ {
+ return $this->_protect_identifiers($item, $first_word_only);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * "Smart" Escape String
+ *
+ * Escapes data based on type
+ * Sets boolean and null types
+ *
+ * @access public
+ * @param string
+ * @return integer
+ */
+ function escape($str)
+ {
+ switch (gettype($str))
+ {
+ case 'string' : $str = "'".$this->escape_str($str)."'";
+ break;
+ case 'boolean' : $str = ($str === FALSE) ? 0 : 1;
+ break;
+ default : $str = ($str === NULL) ? 'NULL' : $str;
+ break;
+ }
+
+ return $str;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Primary
+ *
+ * Retrieves the primary key. It assumes that the row in the first
+ * position is the primary key
+ *
+ * @access public
+ * @param string the table name
+ * @return string
+ */
+ function primary($table = '')
+ {
+ $fields = $this->list_fields($table);
+
+ if ( ! is_array($fields))
+ {
+ return FALSE;
+ }
+
+ return current($fields);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns an array of table names
+ *
+ * @access public
+ * @return array
+ */
+ function list_tables($constrain_by_prefix = FALSE)
+ {
+ // Is there a cached result?
+ if (isset($this->data_cache['table_names']))
+ {
+ return $this->data_cache['table_names'];
+ }
+
+ if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix)))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_unsupported_function');
+ }
+ return FALSE;
+ }
+
+ $retval = array();
+ $query = $this->query($sql);
+
+ if ($query->num_rows() > 0)
+ {
+ foreach($query->result_array() as $row)
+ {
+ if (isset($row['TABLE_NAME']))
+ {
+ $retval[] = $row['TABLE_NAME'];
+ }
+ else
+ {
+ $retval[] = array_shift($row);
+ }
+ }
+ }
+
+ $this->data_cache['table_names'] = $retval;
+ return $this->data_cache['table_names'];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Determine if a particular table exists
+ * @access public
+ * @return boolean
+ */
+ function table_exists($table_name)
+ {
+ return ( ! in_array($this->prep_tablename($table_name), $this->list_tables())) ? FALSE : TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch MySQL Field Names
+ *
+ * @access public
+ * @param string the table name
+ * @return array
+ */
+ function list_fields($table = '')
+ {
+ // Is there a cached result?
+ if (isset($this->data_cache['field_names'][$table]))
+ {
+ return $this->data_cache['field_names'][$table];
+ }
+
+ if ($table == '')
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_field_param_missing');
+ }
+ return FALSE;
+ }
+
+ if (FALSE === ($sql = $this->_list_columns($this->prep_tablename($table))))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_unsupported_function');
+ }
+ return FALSE;
+ }
+
+ $query = $this->query($sql);
+
+ $retval = array();
+ foreach($query->result_array() as $row)
+ {
+ if (isset($row['COLUMN_NAME']))
+ {
+ $retval[] = $row['COLUMN_NAME'];
+ }
+ else
+ {
+ $retval[] = current($row);
+ }
+ }
+
+ $this->data_cache['field_names'][$table] = $retval;
+ return $this->data_cache['field_names'][$table];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Determine if a particular field exists
+ * @access public
+ * @param string
+ * @param string
+ * @return boolean
+ */
+ function field_exists($field_name, $table_name)
+ {
+ return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * DEPRECATED - use list_fields()
+ */
+ function field_names($table = '')
+ {
+ return $this->list_fields($table);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns an object with field data
+ *
+ * @access public
+ * @param string the table name
+ * @return object
+ */
+ function field_data($table = '')
+ {
+ if ($table == '')
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_field_param_missing');
+ }
+ return FALSE;
+ }
+
+ $query = $this->query($this->_field_data($this->prep_tablename($table)));
+ return $query->field_data();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Generate an insert string
+ *
+ * @access public
+ * @param string the table upon which the query will be performed
+ * @param array an associative array data of key/values
+ * @return string
+ */
+ function insert_string($table, $data)
+ {
+ $fields = array();
+ $values = array();
+
+ foreach($data as $key => $val)
+ {
+ $fields[] = $key;
+ $values[] = $this->escape($val);
+ }
+
+
+ return $this->_insert($this->prep_tablename($table), $fields, $values);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Generate an update string
+ *
+ * @access public
+ * @param string the table upon which the query will be performed
+ * @param array an associative array data of key/values
+ * @param mixed the "where" statement
+ * @return string
+ */
+ function update_string($table, $data, $where)
+ {
+ if ($where == '')
+ return false;
+
+ $fields = array();
+ foreach($data as $key => $val)
+ {
+ $fields[$key] = $this->escape($val);
+ }
+
+ if ( ! is_array($where))
+ {
+ $dest = array($where);
+ }
+ else
+ {
+ $dest = array();
+ foreach ($where as $key => $val)
+ {
+ $prefix = (count($dest) == 0) ? '' : ' AND ';
+
+ if ($val !== '')
+ {
+ if ( ! $this->_has_operator($key))
+ {
+ $key .= ' =';
+ }
+
+ $val = ' '.$this->escape($val);
+ }
+
+ $dest[] = $prefix.$key.$val;
+ }
+ }
+
+ return $this->_update($this->prep_tablename($table), $fields, $dest);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Prep the table name - simply adds the table prefix if needed
+ *
+ * @access public
+ * @param string the table name
+ * @return string
+ */
+ function prep_tablename($table = '')
+ {
+ // Do we need to add the table prefix?
+ if ($this->dbprefix != '')
+ {
+ if (substr($table, 0, strlen($this->dbprefix)) != $this->dbprefix)
+ {
+ $table = $this->dbprefix.$table;
+ }
+ }
+
+ return $table;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Enables a native PHP function to be run, using a platform agnostic wrapper.
+ *
+ * @access public
+ * @param string the function name
+ * @param mixed any parameters needed by the function
+ * @return mixed
+ */
+ function call_function($function)
+ {
+ $driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';
+
+ if (FALSE === strpos($driver, $function))
+ {
+ $function = $driver.$function;
+ }
+
+ if ( ! function_exists($function))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_unsupported_function');
+ }
+ return FALSE;
+ }
+ else
+ {
+ $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;
+
+ return call_user_func_array($function, $args);
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set Cache Directory Path
+ *
+ * @access public
+ * @param string the path to the cache directory
+ * @return void
+ */
+ function cache_set_path($path = '')
+ {
+ $this->cachedir = $path;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Enable Query Caching
+ *
+ * @access public
+ * @return void
+ */
+ function cache_on()
+ {
+ $this->cache_on = TRUE;
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Disable Query Caching
+ *
+ * @access public
+ * @return void
+ */
+ function cache_off()
+ {
+ $this->cache_on = FALSE;
+ return FALSE;
+ }
+
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete the cache files associated with a particular URI
+ *
+ * @access public
+ * @return void
+ */
+ function cache_delete($segment_one = '', $segment_two = '')
+ {
+ if ( ! $this->_cache_init())
+ {
+ return FALSE;
+ }
+ return $this->CACHE->delete($segment_one, $segment_two);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete All cache files
+ *
+ * @access public
+ * @return void
+ */
+ function cache_delete_all()
+ {
+ if ( ! $this->_cache_init())
+ {
+ return FALSE;
+ }
+
+ return $this->CACHE->delete_all();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Initialize the Cache Class
+ *
+ * @access private
+ * @return void
+ */
+ function _cache_init()
+ {
+ if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))
+ {
+ return TRUE;
+ }
+
+ if ( ! @include(BASEPATH.'database/DB_cache'.EXT))
+ {
+ return $this->cache_off();
+ }
+
+ $this->CACHE = new CI_DB_Cache;
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Close DB Connection
+ *
+ * @access public
+ * @return void
+ */
+ function close()
+ {
+ if (is_resource($this->conn_id))
+ {
+ $this->_close($this->conn_id);
+ }
+ $this->conn_id = FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Display an error message
+ *
+ * @access public
+ * @param string the error message
+ * @param string any "swap" values
+ * @param boolean whether to localize the message
+ * @return string sends the application/error_db.php template
+ */
+ function display_error($error = '', $swap = '', $native = FALSE)
+ {
+// $LANG = new CI_Lang();
+ $LANG = new CI_Language();
+ $LANG->load('db');
+
+ $heading = 'Database Error';
+
+ if ($native == TRUE)
+ {
+ $message = $error;
+ }
+ else
+ {
+ $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;
+ }
+
+ if ( ! class_exists('CI_Exceptions'))
+ {
+// include(BASEPATH.'core/Exceptions'.EXT);
+ include(BASEPATH.'libraries/Exceptions'.EXT);
+ }
+
+ $error = new CI_Exceptions();
+ echo $error->show_error('An Error Was Encountered', $message, 'error_db');
+ exit;
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/system/database/.svn/text-base/DB_forge.php.svn-base b/system/database/.svn/text-base/DB_forge.php.svn-base
new file mode 100644
index 0000000..cd468bc
--- /dev/null
+++ b/system/database/.svn/text-base/DB_forge.php.svn-base
@@ -0,0 +1,322 @@
+db
+ $CI =& get_instance();
+ $this->db =& $CI->db;
+ log_message('debug', "Database Forge Class Initialized");
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Create database
+ *
+ * @access public
+ * @param string the database name
+ * @return bool
+ */
+ function create_database($db_name)
+ {
+ $sql = $this->_create_database($db_name);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Drop database
+ *
+ * @access public
+ * @param string the database name
+ * @return bool
+ */
+ function drop_database($db_name)
+ {
+ $sql = $this->_drop_database($db_name);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Add Key
+ *
+ * @access public
+ * @param string key
+ * @param string type
+ * @return void
+ */
+ function add_key($key = '', $primary = FALSE)
+ {
+ if ($key == '')
+ {
+ show_error('Key information is required for that operation.');
+ }
+
+ if ($primary === TRUE)
+ {
+ $this->primary_keys[] = $key;
+ }
+ else
+ {
+ $this->keys[] = $key;
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Add Field
+ *
+ * @access public
+ * @param string collation
+ * @return void
+ */
+ function add_field($field = '')
+ {
+ if ($field == '')
+ {
+ show_error('Field information is required.');
+ }
+
+ if (is_string($field))
+ {
+ if ($field == 'id')
+ {
+ $this->fields[] = array('id' => array(
+ 'type' => 'INT',
+ 'constraint' => 9,
+ 'auto_increment' => TRUE
+ )
+ );
+ $this->add_key('id', TRUE);
+ }
+ else
+ {
+ if (strpos($field, ' ') === FALSE)
+ {
+ show_error('Field information is required for that operation.');
+ }
+
+ $this->fields[] = $field;
+ }
+ }
+
+ if (is_array($field))
+ {
+ $this->fields = array_merge($this->fields, $field);
+ }
+
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Create Table
+ *
+ * @access public
+ * @param string the table name
+ * @return bool
+ */
+ function create_table($table = '', $if_not_exists = FALSE)
+ {
+ if ($table == '')
+ {
+ show_error('A table name is required for that operation.');
+ }
+
+ if (count($this->fields) == 0)
+ {
+ show_error('Field information is required.');
+ }
+
+ $sql = $this->_create_table($this->db->dbprefix.$table, $this->fields, $this->primary_keys, $this->keys, $if_not_exists);
+
+ $this->_reset();
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Drop Table
+ *
+ * @access public
+ * @param string the table name
+ * @return bool
+ */
+ function drop_table($table_name)
+ {
+ $sql = $this->_drop_table($this->db->dbprefix.$table_name);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Column Add
+ *
+ * @access public
+ * @param string the table name
+ * @param string the column name
+ * @param string the column definition
+ * @return bool
+ */
+ function add_column($table = '', $field = array(), $after_field = '')
+ {
+ if ($table == '')
+ {
+ show_error('A table name is required for that operation.');
+ }
+
+ // add field info into field array, but we can only do one at a time
+ // so only grab the first field in the event there are more then one
+ $this->add_field(array_slice($field, 0, 1));
+
+ if (count($this->fields) == 0)
+ {
+ show_error('Field information is required.');
+ }
+
+ $sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field);
+
+ $this->_reset();
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Column Drop
+ *
+ * @access public
+ * @param string the table name
+ * @param string the column name
+ * @return bool
+ */
+ function drop_column($table = '', $column_name = '')
+ {
+
+ if ($table == '')
+ {
+ show_error('A table name is required for that operation.');
+ }
+
+ if ($column_name == '')
+ {
+ show_error('A column name is required for that operation.');
+ }
+
+ $sql = $this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name);
+
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Column Modify
+ *
+ * @access public
+ * @param string the table name
+ * @param string the column name
+ * @param string the column definition
+ * @return bool
+ */
+ function modify_column($table = '', $field = array())
+ {
+
+ if ($table == '')
+ {
+ show_error('A table name is required for that operation.');
+ }
+
+ // add field info into field array, but we can only do one at a time
+ // so only grab the first field in the event there are more then one
+ $this->add_field(array_slice($field, 0, 1));
+
+ if (count($this->fields) == 0)
+ {
+ show_error('Field information is required.');
+ }
+
+ $sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields);
+
+ $this->_reset();
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Reset
+ *
+ * Resets table creation vars
+ *
+ * @access private
+ * @return void
+ */
+ function _reset()
+ {
+ $this->fields = array();
+ $this->keys = array();
+ $this->primary_keys = array();
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/system/database/.svn/text-base/DB_result.php.svn-base b/system/database/.svn/text-base/DB_result.php.svn-base
new file mode 100644
index 0000000..7d50979
--- /dev/null
+++ b/system/database/.svn/text-base/DB_result.php.svn-base
@@ -0,0 +1,340 @@
+result_object() : $this->result_array();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Query result. "object" version.
+ *
+ * @access public
+ * @return object
+ */
+ function result_object()
+ {
+ if (count($this->result_object) > 0)
+ {
+ return $this->result_object;
+ }
+
+ // In the event that query caching is on the result_id variable
+ // will return FALSE since there isn't a valid SQL resource so
+ // we'll simply return an empty array.
+ if ($this->result_id === FALSE OR $this->num_rows() == 0)
+ {
+ return array();
+ }
+
+ $this->_data_seek(0);
+ while ($row = $this->_fetch_object())
+ {
+ $this->result_object[] = $row;
+ }
+
+ return $this->result_object;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Query result. "array" version.
+ *
+ * @access public
+ * @return array
+ */
+ function result_array()
+ {
+ if (count($this->result_array) > 0)
+ {
+ return $this->result_array;
+ }
+
+ // In the event that query caching is on the result_id variable
+ // will return FALSE since there isn't a valid SQL resource so
+ // we'll simply return an empty array.
+ if ($this->result_id === FALSE OR $this->num_rows() == 0)
+ {
+ return array();
+ }
+
+ $this->_data_seek(0);
+ while ($row = $this->_fetch_assoc())
+ {
+ $this->result_array[] = $row;
+ }
+
+ return $this->result_array;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Query result. Acts as a wrapper function for the following functions.
+ *
+ * @access public
+ * @param string
+ * @param string can be "object" or "array"
+ * @return mixed either a result object or array
+ */
+ function row($n = 0, $type = 'object')
+ {
+ if ( ! is_numeric($n))
+ {
+ // We cache the row data for subsequent uses
+ if ( ! is_array($this->row_data))
+ {
+ $this->row_data = $this->row_array(0);
+ }
+
+ if (isset($this->row_data[$n]))
+ {
+ return $this->row_data[$n];
+ }
+ // reset the $n variable if the result was not achieved
+ $n = 0;
+ }
+
+ return ($type == 'object') ? $this->row_object($n) : $this->row_array($n);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Assigns an item into a particular column slot
+ *
+ * @access public
+ * @return object
+ */
+ function set_row($key, $value = NULL)
+ {
+ // We cache the row data for subsequent uses
+ if ( ! is_array($this->row_data))
+ {
+ $this->row_data = $this->row_array(0);
+ }
+
+ if (is_array($key))
+ {
+ foreach ($key as $k => $v)
+ {
+ $this->row_data[$k] = $v;
+ }
+
+ return;
+ }
+
+ if ($key != '' AND ! is_null($value))
+ {
+ $this->row_data[$key] = $value;
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns a single result row - object version
+ *
+ * @access public
+ * @return object
+ */
+ function row_object($n = 0)
+ {
+ $result = $this->result_object();
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+
+ if ($n != $this->current_row AND isset($result[$n]))
+ {
+ $this->current_row = $n;
+ }
+
+ return $result[$this->current_row];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns a single result row - array version
+ *
+ * @access public
+ * @return array
+ */
+ function row_array($n = 0)
+ {
+ $result = $this->result_array();
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+
+ if ($n != $this->current_row AND isset($result[$n]))
+ {
+ $this->current_row = $n;
+ }
+
+ return $result[$this->current_row];
+ }
+
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the "first" row
+ *
+ * @access public
+ * @return object
+ */
+ function first_row($type = 'object')
+ {
+ $result = $this->result($type);
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+ return $result[0];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the "last" row
+ *
+ * @access public
+ * @return object
+ */
+ function last_row($type = 'object')
+ {
+ $result = $this->result($type);
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+ return $result[count($result) -1];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the "next" row
+ *
+ * @access public
+ * @return object
+ */
+ function next_row($type = 'object')
+ {
+ $result = $this->result($type);
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+
+ if (isset($result[$this->current_row + 1]))
+ {
+ ++$this->current_row;
+ }
+
+ return $result[$this->current_row];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the "previous" row
+ *
+ * @access public
+ * @return object
+ */
+ function previous_row($type = 'object')
+ {
+ $result = $this->result($type);
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+
+ if (isset($result[$this->current_row - 1]))
+ {
+ --$this->current_row;
+ }
+ return $result[$this->current_row];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * The following functions are normally overloaded by the identically named
+ * methods in the platform-specific driver -- except when query caching
+ * is used. When caching is enabled we do not load the other driver.
+ * These functions are primarily here to prevent undefined function errors
+ * when a cached result object is in use. They are not otherwise fully
+ * operational due to the unavailability of the database resource IDs with
+ * cached results.
+ */
+ function num_rows() { return $this->num_rows; }
+ function num_fields() { return 0; }
+ function list_fields() { return array(); }
+ function field_names() { return array(); } // Deprecated
+ function field_data() { return array(); }
+ function free_result() { return TRUE; }
+ function _data_seek() { return TRUE; }
+ function _fetch_assoc() { return array(); }
+ function _fetch_object() { return array(); }
+
+}
+// END DB_result class
+?>
\ No newline at end of file
diff --git a/system/database/.svn/text-base/DB_utility.php.svn-base b/system/database/.svn/text-base/DB_utility.php.svn-base
new file mode 100644
index 0000000..d9b8fed
--- /dev/null
+++ b/system/database/.svn/text-base/DB_utility.php.svn-base
@@ -0,0 +1,387 @@
+db
+ $CI =& get_instance();
+ $this->db =& $CI->db;
+
+ log_message('debug', "Database Utility Class Initialized");
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * List databases
+ *
+ * @access public
+ * @return bool
+ */
+ function list_databases()
+ {
+ // Is there a cached result?
+ if (isset($this->data_cache['db_names']))
+ {
+ return $this->data_cache['db_names'];
+ }
+
+ $query = $this->db->query($this->_list_databases());
+ $dbs = array();
+ if ($query->num_rows() > 0)
+ {
+ foreach ($query->result_array() as $row)
+ {
+ $dbs[] = current($row);
+ }
+ }
+
+ $this->data_cache['db_names'] = $dbs;
+ return $this->data_cache['db_names'];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Optimize Table
+ *
+ * @access public
+ * @param string the table name
+ * @return bool
+ */
+ function optimize_table($table_name)
+ {
+ $sql = $this->_optimize_table($table_name);
+
+ if (is_bool($sql))
+ {
+ show_error('db_must_use_set');
+ }
+
+ $query = $this->db->query($sql);
+ $res = $query->result_array();
+
+ // Note: Due to a bug in current() that affects some versions
+ // of PHP we can not pass function call directly into it
+ return current($res);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Optimize Database
+ *
+ * @access public
+ * @return array
+ */
+ function optimize_database()
+ {
+ $result = array();
+ foreach ($this->db->list_tables() as $table_name)
+ {
+ $sql = $this->_optimize_table($table_name);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ $query = $this->db->query($sql);
+
+ // Build the result array...
+ // Note: Due to a bug in current() that affects some versions
+ // of PHP we can not pass function call directly into it
+ $res = $query->result_array();
+ $res = current($res);
+ $key = str_replace($this->db->database.'.', '', current($res));
+ $keys = array_keys($res);
+ unset($res[$keys[0]]);
+
+ $result[$key] = $res;
+ }
+
+ return $result;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Repair Table
+ *
+ * @access public
+ * @param string the table name
+ * @return bool
+ */
+ function repair_table($table_name)
+ {
+ $sql = $this->_repair_table($table_name);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ $query = $this->db->query($sql);
+
+ // Note: Due to a bug in current() that affects some versions
+ // of PHP we can not pass function call directly into it
+ $res = $query->result_array();
+ return current($res);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Generate CSV from a query result object
+ *
+ * @access public
+ * @param object The query result object
+ * @param string The delimiter - comma by default
+ * @param string The newline character - \n by default
+ * @param string The enclosure - double quote by default
+ * @return string
+ */
+ function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"')
+ {
+ if ( ! is_object($query) OR ! method_exists($query, 'field_names'))
+ {
+ show_error('You must submit a valid result object');
+ }
+
+ $out = '';
+
+ // First generate the headings from the table column names
+ foreach ($query->list_fields() as $name)
+ {
+ $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
+ }
+
+ $out = rtrim($out);
+ $out .= $newline;
+
+ // Next blast through the result array and build out the rows
+ foreach ($query->result_array() as $row)
+ {
+ foreach ($row as $item)
+ {
+ $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;
+ }
+ $out = rtrim($out);
+ $out .= $newline;
+ }
+
+ return $out;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Generate XML data from a query result object
+ *
+ * @access public
+ * @param object The query result object
+ * @param array Any preferences
+ * @return string
+ */
+ function xml_from_result($query, $params = array())
+ {
+ if ( ! is_object($query) OR ! method_exists($query, 'field_names'))
+ {
+ show_error('You must submit a valid result object');
+ }
+
+ // Set our default values
+ foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
+ {
+ if ( ! isset($params[$key]))
+ {
+ $params[$key] = $val;
+ }
+ }
+
+ // Create variables for convenience
+ extract($params);
+
+ // Load the xml helper
+ $CI =& get_instance();
+ $CI->load->helper('xml');
+
+ // Generate the result
+ $xml = "<{$root}>".$newline;
+ foreach ($query->result_array() as $row)
+ {
+ $xml .= $tab."<{$element}>".$newline;
+
+ foreach ($row as $key => $val)
+ {
+ $xml .= $tab.$tab."<{$key}>".xml_convert($val)."{$key}>".$newline;
+ }
+ $xml .= $tab."{$element}>".$newline;
+ }
+ $xml .= "$root>".$newline;
+
+ return $xml;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Database Backup
+ *
+ * @access public
+ * @return void
+ */
+ function backup($params = array())
+ {
+ // If the parameters have not been submitted as an
+ // array then we know that it is simply the table
+ // name, which is a valid short cut.
+ if (is_string($params))
+ {
+ $params = array('tables' => $params);
+ }
+
+ // ------------------------------------------------------
+
+ // Set up our default preferences
+ $prefs = array(
+ 'tables' => array(),
+ 'ignore' => array(),
+ 'filename' => '',
+ 'format' => 'gzip', // gzip, zip, txt
+ 'add_drop' => TRUE,
+ 'add_insert' => TRUE,
+ 'newline' => "\n"
+ );
+
+ // Did the user submit any preferences? If so set them....
+ if (count($params) > 0)
+ {
+ foreach ($prefs as $key => $val)
+ {
+ if (isset($params[$key]))
+ {
+ $prefs[$key] = $params[$key];
+ }
+ }
+ }
+
+ // ------------------------------------------------------
+
+ // Are we backing up a complete database or individual tables?
+ // If no table names were submitted we'll fetch the entire table list
+ if (count($prefs['tables']) == 0)
+ {
+ $prefs['tables'] = $this->db->list_tables();
+ }
+
+ // ------------------------------------------------------
+
+ // Validate the format
+ if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
+ {
+ $prefs['format'] = 'txt';
+ }
+
+ // ------------------------------------------------------
+
+ // Is the encoder supported? If not, we'll either issue an
+ // error or use plain text depending on the debug settings
+ if (($prefs['format'] == 'gzip' AND ! @function_exists('gzencode'))
+ OR ($prefs['format'] == 'zip' AND ! @function_exists('gzcompress')))
+ {
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_compression');
+ }
+
+ $prefs['format'] = 'txt';
+ }
+
+ // ------------------------------------------------------
+
+ // Set the filename if not provided - Only needed with Zip files
+ if ($prefs['filename'] == '' AND $prefs['format'] == 'zip')
+ {
+ $prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database;
+ $prefs['filename'] .= '_'.date('Y-m-d_H-i', time());
+ }
+
+ // ------------------------------------------------------
+
+ // Was a Gzip file requested?
+ if ($prefs['format'] == 'gzip')
+ {
+ return gzencode($this->_backup($prefs));
+ }
+
+ // ------------------------------------------------------
+
+ // Was a text file requested?
+ if ($prefs['format'] == 'txt')
+ {
+ return $this->_backup($prefs);
+ }
+
+ // ------------------------------------------------------
+
+ // Was a Zip file requested?
+ if ($prefs['format'] == 'zip')
+ {
+ // If they included the .zip file extension we'll remove it
+ if (preg_match("|.+?\.zip$|", $prefs['filename']))
+ {
+ $prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
+ }
+
+ // Tack on the ".sql" file extension if needed
+ if ( ! preg_match("|.+?\.sql$|", $prefs['filename']))
+ {
+ $prefs['filename'] .= '.sql';
+ }
+
+ // Load the Zip class and output it
+
+ $CI =& get_instance();
+ $CI->load->library('zip');
+ $CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
+ return $CI->zip->get_zip();
+ }
+
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/system/database/.svn/text-base/index.html.svn-base b/system/database/.svn/text-base/index.html.svn-base
new file mode 100644
index 0000000..5a1f5d6
--- /dev/null
+++ b/system/database/.svn/text-base/index.html.svn-base
@@ -0,0 +1,15 @@
+
+
+
+
+403 Forbidden
+
+
+
+
+
+
Directory access is forbidden.
+
+
+
+
\ No newline at end of file
diff --git a/system/database/DB.php b/system/database/DB.php
new file mode 100755
index 0000000..c3e7722
--- /dev/null
+++ b/system/database/DB.php
@@ -0,0 +1,123 @@
+ $dns['scheme'],
+ 'hostname' => (isset($dns['host'])) ? rawurldecode($dns['host']) : '',
+ 'username' => (isset($dns['user'])) ? rawurldecode($dns['user']) : '',
+ 'password' => (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '',
+ 'database' => (isset($dns['path'])) ? rawurldecode(substr($dns['host'], 1)) : ''
+ );
+ }
+
+ // No DB specified yet? Beat them senseless...
+ if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')
+ {
+ show_error('You have not selected a database type to connect to.');
+ }
+
+ // Load the DB classes. Note: Since the active record class is optional
+ // we need to dynamically create a class that extends proper parent class
+ // based on whether we're using the active record class or not.
+ // Kudos to Paul for discovering this clever use of eval()
+
+ if ($active_record_override == TRUE)
+ {
+ $active_record = TRUE;
+ }
+
+ require_once(BASEPATH.'database/DB_driver'.EXT);
+
+ if (! isset($active_record) OR $active_record == TRUE)
+ {
+ require_once(BASEPATH.'database/DB_active_rec'.EXT);
+
+ if ( ! class_exists('CI_DB'))
+ {
+ eval('class CI_DB extends CI_DB_active_record { }');
+ }
+ }
+ else
+ {
+ if ( ! class_exists('CI_DB'))
+ {
+ eval('class CI_DB extends CI_DB_driver { }');
+ }
+ }
+
+ require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT);
+
+ // Instantiate the DB adapter
+ $driver = 'CI_DB_'.$params['dbdriver'].'_driver';
+ $DB =& new $driver($params);
+
+ if ($DB->autoinit == TRUE)
+ {
+ $DB->initialize();
+ }
+
+ return $DB;
+}
+
+
+?>
\ No newline at end of file
diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php
new file mode 100755
index 0000000..263172a
--- /dev/null
+++ b/system/database/DB_active_rec.php
@@ -0,0 +1,1733 @@
+display_error('db_table_name_required');
+ }
+
+ return $this->dbprefix.$table;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select
+ *
+ * Generates the SELECT portion of the query
+ *
+ * @access public
+ * @param string
+ * @return object
+ */
+ function select($select = '*', $protect_identifiers = TRUE)
+ {
+ if (is_string($select))
+ {
+ $select = explode(',', $select);
+ }
+
+ foreach ($select as $val)
+ {
+ $val = trim($val);
+
+ if ($val != '*' && $protect_identifiers !== FALSE)
+ {
+ if (strpos($val, '.') !== FALSE)
+ {
+ $val = $this->dbprefix.$val;
+ }
+ else
+ {
+ $val = $this->_protect_identifiers($val);
+ }
+ }
+
+ if ($val != '')
+ {
+ $this->ar_select[] = $val;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_select[] = $val;
+ }
+ }
+ }
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select Max
+ *
+ * Generates a SELECT MAX(field) portion of a query
+ *
+ * @access public
+ * @param string the field
+ * @param string an alias
+ * @return object
+ */
+ function select_max($select = '', $alias='')
+ {
+ if (!is_string($select) || $select == '')
+ {
+ $this->display_error('db_invalid_query');
+ }
+
+ $alias = ($alias != '') ? $alias : $select;
+
+ $sql = 'MAX('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias));
+
+ $this->ar_select[] = $sql;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_select[] = $sql;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select Min
+ *
+ * Generates a SELECT MIN(field) portion of a query
+ *
+ * @access public
+ * @param string the field
+ * @param string an alias
+ * @return object
+ */
+ function select_min($select = '', $alias='')
+ {
+ if (!is_string($select) || $select == '')
+ {
+ $this->display_error('db_invalid_query');
+ }
+
+ $alias = ($alias != '') ? $alias : $select;
+
+ $sql = 'MIN('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias));
+
+ $this->ar_select[] = $sql;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_select[] = $sql;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select Average
+ *
+ * Generates a SELECT AVG(field) portion of a query
+ *
+ * @access public
+ * @param string the field
+ * @param string an alias
+ * @return object
+ */
+ function select_avg($select = '', $alias='')
+ {
+ if (!is_string($select) || $select == '')
+ {
+ $this->display_error('db_invalid_query');
+ }
+
+ $alias = ($alias != '') ? $alias : $select;
+
+ $sql = 'AVG('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias));
+
+ $this->ar_select[] = $sql;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_select[] = $sql;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Select Sum
+ *
+ * Generates a SELECT SUM(field) portion of a query
+ *
+ * @access public
+ * @param string the field
+ * @param string an alias
+ * @return object
+ */
+ function select_sum($select = '', $alias='')
+ {
+ if (!is_string($select) || $select == '')
+ {
+ $this->display_error('db_invalid_query');
+ }
+
+ $alias = ($alias != '') ? $alias : $select;
+
+ $sql = 'SUM('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias));
+
+ $this->ar_select[] = $sql;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_select[] = $sql;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * DISTINCT
+ *
+ * Sets a flag which tells the query string compiler to add DISTINCT
+ *
+ * @access public
+ * @param bool
+ * @return object
+ */
+ function distinct($val = TRUE)
+ {
+ $this->ar_distinct = (is_bool($val)) ? $val : TRUE;
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * From
+ *
+ * Generates the FROM portion of the query
+ *
+ * @access public
+ * @param mixed can be a string or array
+ * @return object
+ */
+ function from($from)
+ {
+ foreach ((array)$from as $val)
+ {
+ $this->ar_from[] = $this->_protect_identifiers($this->_track_aliases($val));
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_from[] = $this->_protect_identifiers($val);
+ }
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Join
+ *
+ * Generates the JOIN portion of the query
+ *
+ * @access public
+ * @param string
+ * @param string the join condition
+ * @param string the type of join
+ * @return object
+ */
+ function join($table, $cond, $type = '')
+ {
+ if ($type != '')
+ {
+ $type = strtoupper(trim($type));
+
+ if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE))
+ {
+ $type = '';
+ }
+ else
+ {
+ $type .= ' ';
+ }
+ }
+
+ // If a DB prefix is used we might need to add it to the column names
+ if ($this->dbprefix)
+ {
+ $this->_track_aliases($table);
+
+ // First we remove any existing prefixes in the condition to avoid duplicates
+ $cond = preg_replace('|('.$this->dbprefix.')([\w\.]+)([\W\s]+)|', "$2$3", $cond);
+
+ // Next we add the prefixes to the condition
+ $cond = preg_replace('|([\w\.]+)([\W\s]+)(.+)|', $this->dbprefix . "$1$2" . $this->dbprefix . "$3", $cond);
+ }
+
+ $join = $type.'JOIN '.$this->_protect_identifiers($this->dbprefix.$table, TRUE).' ON '.$cond;
+
+ $this->ar_join[] = $join;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_join[] = $join;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where
+ *
+ * Generates the WHERE portion of the query. Separates
+ * multiple calls with AND
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function where($key, $value = NULL, $escape = TRUE)
+ {
+ return $this->_where($key, $value, 'AND ', $escape);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * OR Where
+ *
+ * Generates the WHERE portion of the query. Separates
+ * multiple calls with OR
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function or_where($key, $value = NULL, $escape = TRUE)
+ {
+ return $this->_where($key, $value, 'OR ', $escape);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * orwhere() is an alias of or_where()
+ * this function is here for backwards compatibility, as
+ * orwhere() has been deprecated
+ */
+ function orwhere($key, $value = NULL, $escape = TRUE)
+ {
+ return $this->or_where($key, $value, $escape);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where
+ *
+ * Called by where() or orwhere()
+ *
+ * @access private
+ * @param mixed
+ * @param mixed
+ * @param string
+ * @return object
+ */
+ function _where($key, $value = NULL, $type = 'AND ', $escape = TRUE)
+ {
+ if ( ! is_array($key))
+ {
+ $key = array($key => $value);
+ }
+
+ foreach ($key as $k => $v)
+ {
+ $prefix = (count($this->ar_where) == 0) ? '' : $type;
+
+ if ( ! $this->_has_operator($k) && is_null($key[$k]))
+ {
+ // value appears not to have been set, assign the test to IS NULL
+ $k .= ' IS NULL';
+ }
+
+ if ( ! is_null($v))
+ {
+
+ if ($escape === TRUE)
+ {
+ // exception for "field<=" keys
+ if ($this->_has_operator($k))
+ {
+ $k = preg_replace("/([A-Za-z_0-9]+)/", $this->_protect_identifiers('$1'), $k);
+ }
+ else
+ {
+ $k = $this->_protect_identifiers($k);
+ }
+ }
+
+ if ( ! $this->_has_operator($k))
+ {
+ $k .= ' =';
+ }
+
+ $v = ' '.$this->escape($v);
+ }
+ else
+ {
+ $k = $this->_protect_identifiers($k, TRUE);
+ }
+
+ $this->ar_where[] = $prefix.$k.$v;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_where[] = $prefix.$k.$v;
+ }
+
+ }
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where_in
+ *
+ * Generates a WHERE field IN ('item', 'item') SQL query joined with
+ * AND if appropriate
+ *
+ * @access public
+ * @param string The field to search
+ * @param array The values searched on
+
+ * @return object
+ */
+ function where_in($key = NULL, $values = NULL)
+ {
+ return $this->_where_in($key, $values);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where_in_or
+ *
+ * Generates a WHERE field IN ('item', 'item') SQL query joined with
+ * OR if appropriate
+ *
+ * @access public
+ * @param string The field to search
+ * @param array The values searched on
+
+ * @return object
+ */
+ function or_where_in($key = NULL, $values = NULL)
+ {
+ return $this->_where_in($key, $values, FALSE, 'OR ');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where_not_in
+ *
+ * Generates a WHERE field NOT IN ('item', 'item') SQL query joined
+ * with AND if appropriate
+ *
+ * @access public
+ * @param string The field to search
+ * @param array The values searched on
+
+ * @return object
+ */
+ function where_not_in($key = NULL, $values = NULL)
+ {
+ return $this->_where_in($key, $values, TRUE);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where_not_in_or
+ *
+ * Generates a WHERE field NOT IN ('item', 'item') SQL query joined
+ * with OR if appropriate
+ *
+ * @access public
+ * @param string The field to search
+ * @param array The values searched on
+
+ * @return object
+ */
+ function or_where_not_in($key = NULL, $values = NULL)
+ {
+ return $this->_where_in($key, $values, FALSE, 'OR ');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Where_in
+ *
+ * Called by where_in, where_in_or, where_not_in, where_not_in_or
+ *
+ * @access public
+ * @param string The field to search
+ * @param array The values searched on
+ * @param boolean If the statement whould be IN or NOT IN
+ * @param string
+ * @return object
+ */
+ function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ')
+ {
+ if ($key === NULL || !is_array($values))
+ {
+ return;
+ }
+
+ $not = ($not) ? ' NOT ' : '';
+
+ foreach ($values as $value)
+ {
+ $this->ar_wherein[] = $this->escape($value);
+ }
+
+ $prefix = (count($this->ar_where) == 0) ? '' : $type;
+
+ $where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") ";
+
+ $this->ar_where[] = $where_in;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_where[] = $where_in;
+ }
+
+ // reset the array for multiple calls
+ $this->ar_wherein = array();
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Like
+ *
+ * Generates a %LIKE% portion of the query. Separates
+ * multiple calls with AND
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function like($field, $match = '', $side = 'both')
+ {
+ return $this->_like($field, $match, 'AND ', $side);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Not Like
+ *
+ * Generates a NOT LIKE portion of the query. Separates
+ * multiple calls with AND
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function not_like($field, $match = '', $side = 'both')
+ {
+ return $this->_like($field, $match, 'AND ', $side, ' NOT');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * OR Like
+ *
+ * Generates a %LIKE% portion of the query. Separates
+ * multiple calls with OR
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function or_like($field, $match = '', $side = 'both')
+ {
+ return $this->_like($field, $match, 'OR ', $side);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * OR Not Like
+ *
+ * Generates a NOT LIKE portion of the query. Separates
+ * multiple calls with OR
+ *
+ * @access public
+ * @param mixed
+ * @param mixed
+ * @return object
+ */
+ function or_not_like($field, $match = '', $side = 'both')
+ {
+ return $this->_like($field, $match, 'OR ', $side, 'NOT ');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * orlike() is an alias of or_like()
+ * this function is here for backwards compatibility, as
+ * orlike() has been deprecated
+ */
+ function orlike($field, $match = '', $side = 'both')
+ {
+ return $this->or_like($field, $match, $side);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Like
+ *
+ * Called by like() or orlike()
+ *
+ * @access private
+ * @param mixed
+ * @param mixed
+ * @param string
+ * @return object
+ */
+ function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '')
+ {
+ if ( ! is_array($field))
+ {
+ $field = array($field => $match);
+ }
+
+ foreach ($field as $k => $v)
+ {
+
+ $k = $this->_protect_identifiers($k);
+
+ $prefix = (count($this->ar_like) == 0) ? '' : $type;
+
+ $v = $this->escape_str($v);
+
+ if ($side == 'before')
+ {
+ $like_statement = $prefix." $k $not LIKE '%{$v}'";
+ }
+ elseif ($side == 'after')
+ {
+ $like_statement = $prefix." $k $not LIKE '{$v}%'";
+ }
+ else
+ {
+ $like_statement = $prefix." $k $not LIKE '%{$v}%'";
+ }
+
+ $this->ar_like[] = $like_statement;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_like[] = $like_statement;
+ }
+
+ }
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * GROUP BY
+ *
+ * @access public
+ * @param string
+ * @return object
+ */
+ function group_by($by)
+ {
+ if (is_string($by))
+ {
+ $by = explode(',', $by);
+ }
+
+ foreach ($by as $val)
+ {
+ $val = trim($val);
+
+ if ($val != '')
+ {
+ $this->ar_groupby[] = $this->_protect_identifiers($val);
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_groupby[] = $this->_protect_identifiers($val);
+ }
+ }
+ }
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * groupby() is an alias of group_by()
+ * this function is here for backwards compatibility, as
+ * groupby() has been deprecated
+ */
+ function groupby($by)
+ {
+ return $this->group_by($by);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the HAVING value
+ *
+ * Separates multiple calls with AND
+ *
+ * @access public
+ * @param string
+ * @param string
+ * @return object
+ */
+ function having($key, $value = '')
+ {
+ return $this->_having($key, $value, 'AND ');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the OR HAVING value
+ *
+ * Separates multiple calls with OR
+ *
+ * @access public
+ * @param string
+ * @param string
+ * @return object
+ */
+ function orhaving($key, $value = '')
+ {
+ return $this->_having($key, $value, 'OR ');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the HAVING values
+ *
+ * Called by having() or orhaving()
+ *
+ * @access private
+ * @param string
+
+ * @param string
+ * @return object
+ */
+ function _having($key, $value = '', $type = 'AND ')
+ {
+ if ( ! is_array($key))
+ {
+ $key = array($key => $value);
+ }
+
+ foreach ($key as $k => $v)
+ {
+ $prefix = (count($this->ar_having) == 0) ? '' : $type;
+ $k = $this->_protect_identifiers($k);
+
+ if ($v != '')
+ {
+ $v = ' '.$this->escape_str($v);
+ }
+
+ $this->ar_having[] = $prefix.$k.$v;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_having[] = $prefix.$k.$v;
+ }
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the ORDER BY value
+ *
+ * @access public
+ * @param string
+ * @param string direction: asc or desc
+ * @return object
+ */
+ function order_by($orderby, $direction = '')
+ {
+ if (strtolower($direction) == 'random')
+ {
+ $orderby = ''; // Random results want or don't need a field name
+ $direction = $this->_random_keyword;
+ }
+ elseif (trim($direction) != '')
+ {
+ $direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';
+ }
+
+ $orderby_statement = $this->_protect_identifiers($orderby, TRUE).$direction;
+
+ $this->ar_orderby[] = $orderby_statement;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_orderby[] = $orderby_statement;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * orderby() is an alias of order_by()
+ * this function is here for backwards compatibility, as
+ * orderby() has been deprecated
+ */
+ function orderby($orderby, $direction = '')
+ {
+ return $this->order_by($orderby, $direction);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the LIMIT value
+ *
+ * @access public
+ * @param integer the limit value
+ * @param integer the offset value
+ * @return object
+ */
+ function limit($value, $offset = '')
+ {
+ $this->ar_limit = $value;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_limit[] = $value;
+ }
+
+ if ($offset != '')
+ {
+ $this->ar_offset = $offset;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_offset[] = $offset;
+ }
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sets the OFFSET value
+ *
+ * @access public
+ * @param integer the offset value
+ * @return object
+ */
+ function offset($offset)
+ {
+ $this->ar_offset = $offset;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_offset[] = $offset;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * The "set" function. Allows key/value pairs to be set for inserting or updating
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param boolean
+ * @return object
+ */
+ function set($key, $value = '', $escape = TRUE)
+ {
+ $key = $this->_object_to_array($key);
+
+ if ( ! is_array($key))
+ {
+ $key = array($key => $value);
+ }
+
+ foreach ($key as $k => $v)
+ {
+ if ($escape === FALSE)
+ {
+ $this->ar_set[$this->_protect_identifiers($k)] = $v;
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_offset[$this->_protect_identifiers($k)] = $v;
+ }
+ }
+ else
+ {
+ $this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v);
+ if ($this->ar_caching === TRUE)
+ {
+ $this->ar_cache_offset[$this->_protect_identifiers($k)] = $this->escape($v);
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get
+ *
+ * Compiles the select statement based on the other functions called
+ * and runs the query
+ *
+ * @access public
+ * @param string the table
+ * @param string the limit clause
+ * @param string the offset clause
+ * @return object
+ */
+ function get($table = '', $limit = null, $offset = null)
+ {
+ if ($table != '')
+ {
+ $this->_track_aliases($table);
+ $this->from($table);
+ }
+
+ if ( ! is_null($limit))
+ {
+ $this->limit($limit, $offset);
+ }
+
+ $sql = $this->_compile_select();
+
+ $result = $this->query($sql);
+ $this->_reset_select();
+ return $result;
+ }
+
+ /**
+ * "Count All Results" query
+ *
+ * Generates a platform-specific query string that counts all records
+ * returned by an Active Record query.
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+ function count_all_results($table = '')
+ {
+ if ($table != '')
+ {
+ $this->_track_aliases($table);
+ $this->from($table);
+ }
+
+ $sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows'));
+
+ $query = $this->query($sql);
+ $this->_reset_select();
+
+ if ($query->num_rows() == 0)
+ {
+ return '0';
+ }
+
+ $row = $query->row();
+ return $row->numrows;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get_Where
+ *
+ * Allows the where clause, limit and offset to be added directly
+ *
+ * @access public
+ * @param string the where clause
+ * @param string the limit clause
+ * @param string the offset clause
+ * @return object
+ */
+ function get_where($table = '', $where = null, $limit = null, $offset = null)
+ {
+ if ($table != '')
+ {
+ $this->_track_aliases($table);
+ $this->from($table);
+ }
+
+ if ( ! is_null($where))
+ {
+ $this->where($where);
+ }
+
+ if ( ! is_null($limit))
+ {
+ $this->limit($limit, $offset);
+ }
+
+ $sql = $this->_compile_select();
+
+ $result = $this->query($sql);
+ $this->_reset_select();
+ return $result;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * getwhere() is an alias of get_where()
+ * this function is here for backwards compatibility, as
+ * getwhere() has been deprecated
+ */
+ function getwhere($table = '', $where = null, $limit = null, $offset = null)
+ {
+ return $this->get_where($table, $where, $limit, $offset);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Insert
+ *
+ * Compiles an insert string and runs the query
+ *
+ * @access public
+ * @param string the table to retrieve the results from
+ * @param array an associative array of insert values
+ * @return object
+ */
+ function insert($table = '', $set = NULL)
+ {
+ if ( ! is_null($set))
+ {
+ $this->set($set);
+ }
+
+ if (count($this->ar_set) == 0)
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_use_set');
+ }
+ return FALSE;
+ }
+
+ if ($table == '')
+ {
+ if ( ! isset($this->ar_from[0]))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_set_table');
+ }
+ return FALSE;
+ }
+
+ $table = $this->ar_from[0];
+ }
+
+ $sql = $this->_insert($this->_protect_identifiers($this->dbprefix.$table), array_keys($this->ar_set), array_values($this->ar_set));
+
+ $this->_reset_write();
+ return $this->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Update
+ *
+ * Compiles an update string and runs the query
+ *
+ * @access public
+ * @param string the table to retrieve the results from
+ * @param array an associative array of update values
+ * @param mixed the where clause
+ * @return object
+ */
+ function update($table = '', $set = NULL, $where = NULL, $limit = NULL)
+ {
+ if ( ! is_null($set))
+ {
+ $this->set($set);
+ }
+
+ if (count($this->ar_set) == 0)
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_use_set');
+ }
+ return FALSE;
+ }
+
+ if ($table == '')
+ {
+ if ( ! isset($this->ar_from[0]))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_set_table');
+ }
+ return FALSE;
+ }
+
+ $table = $this->ar_from[0];
+ }
+
+ if ($where != NULL)
+ {
+ $this->where($where);
+ }
+
+ if ($limit != NULL)
+ {
+ $this->limit($limit);
+ }
+
+ $sql = $this->_update($this->_protect_identifiers($this->dbprefix.$table), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);
+
+ $this->_reset_write();
+ return $this->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Empty Table
+ *
+ * Compiles a delete string and runs "DELETE FROM table"
+ *
+ * @access public
+ * @param string the table to empty
+ * @return object
+ */
+ function empty_table($table = '')
+ {
+ if ($table == '')
+ {
+ if ( ! isset($this->ar_from[0]))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_set_table');
+ }
+ return FALSE;
+ }
+
+ $table = $this->ar_from[0];
+ }
+ else
+ {
+ $table = $this->_protect_identifiers($this->dbprefix.$table);
+ }
+
+
+ $sql = $this->_delete($table);
+
+ $this->_reset_write();
+
+ return $this->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Truncate
+ *
+ * Compiles a truncate string and runs the query
+ * If the database does not support the truncate() command
+ * This function maps to "DELETE FROM table"
+ *
+ * @access public
+ * @param string the table to truncate
+ * @return object
+ */
+ function truncate($table = '')
+ {
+ if ($table == '')
+ {
+ if ( ! isset($this->ar_from[0]))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_set_table');
+ }
+ return FALSE;
+ }
+
+ $table = $this->ar_from[0];
+ }
+ else
+ {
+ $table = $this->_protect_identifiers($this->dbprefix.$table);
+ }
+
+
+ $sql = $this->_truncate($table);
+
+ $this->_reset_write();
+
+ return $this->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete
+ *
+ * Compiles a delete string and runs the query
+ *
+ * @access public
+ * @param mixed the table(s) to delete from. String or array
+ * @param mixed the where clause
+ * @param mixed the limit clause
+ * @param boolean
+ * @return object
+ */
+ function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE)
+ {
+ if ($table == '')
+ {
+ if ( ! isset($this->ar_from[0]))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_must_set_table');
+ }
+ return FALSE;
+ }
+
+ $table = $this->ar_from[0];
+ }
+ elseif (is_array($table))
+ {
+ foreach($table as $single_table)
+ {
+ $this->delete($single_table, $where, $limit, FALSE);
+ }
+
+ $this->_reset_write();
+ return;
+ }
+ else
+ {
+ $table = $this->_protect_identifiers($this->dbprefix.$table);
+ }
+
+ if ($where != '')
+ {
+ $this->where($where);
+ }
+
+ if ($limit != NULL)
+ {
+ $this->limit($limit);
+ }
+
+ if (count($this->ar_where) == 0 && count($this->ar_like) == 0)
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_del_must_use_where');
+ }
+
+ return FALSE;
+ }
+
+ $sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit);
+
+ if ($reset_data)
+ {
+ $this->_reset_write();
+ }
+
+ return $this->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Use Table - DEPRECATED
+ *
+ * @deprecated use $this->db->from instead
+ */
+ function use_table($table)
+ {
+ return $this->from($table);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Tests whether the string has an SQL operator
+ *
+ * @access private
+ * @param string
+ * @return bool
+ */
+ function _has_operator($str)
+ {
+ $str = trim($str);
+ if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Track Aliases
+ *
+ * Used to track SQL statements written with aliased tables.
+ *
+ * @access private
+ * @param string The table to inspect
+ * @return string
+ */
+ function _track_aliases($table)
+ {
+ // if a table alias is used we can recognize it by a space
+ if (strpos($table, " ") !== FALSE)
+ {
+ // if the alias is written with the AS keyowrd, get it out
+ $table = preg_replace('/ AS /i', ' ', $table);
+
+ $this->ar_aliased_tables[] = trim(strrchr($table, " "));
+ }
+
+ return $this->dbprefix.$table;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Filter Table Aliases
+ *
+ * Intelligently removes database prefixes from aliased tables
+ *
+ * @access private
+ * @param array An array of compiled SQL
+ * @return array Cleaned up statement with aliases accounted for
+ */
+ function _filter_table_aliases($statements)
+ {
+ foreach ($statements as $k => $v)
+ {
+ foreach ($this->ar_aliased_tables as $table)
+ {
+ $statement = preg_replace('/(\w+\.\w+)/', $this->_protect_identifiers('$0'), $v); // makes `table.field`
+ $statement = str_replace(array($this->dbprefix.$table, '.'), array($table, $this->_protect_identifiers('.')), $statement);
+ }
+
+ $statements[$k] = $statement;
+ }
+
+ return $statements;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Compile the SELECT statement
+ *
+ * Generates a query string based on which functions were used.
+ * Should not be called directly. The get() function calls it.
+ *
+ * @access private
+ * @return string
+ */
+ function _compile_select($select_override = FALSE)
+ {
+ $this->_merge_cache();
+
+ $sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';
+
+ $sql .= (count($this->ar_select) == 0) ? '*' : implode(', ', $this->ar_select);
+
+ if ($select_override !== FALSE)
+ {
+ $sql = $select_override;
+ }
+
+ if (count($this->ar_from) > 0)
+ {
+ $sql .= "\nFROM ";
+ $sql .= $this->_from_tables($this->ar_from);
+ }
+
+ if (count($this->ar_join) > 0)
+ {
+ $sql .= "\n";
+
+ // special consideration for table aliases
+ if (count($this->ar_aliased_tables) > 0 && $this->dbprefix)
+ {
+ $sql .= implode("\n", $this->_filter_table_aliases($this->ar_join));
+ }
+ else
+ {
+ $sql .= implode("\n", $this->ar_join);
+ }
+
+ }
+
+ if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)
+ {
+ $sql .= "\nWHERE ";
+ }
+
+ $sql .= implode("\n", $this->ar_where);
+
+ if (count($this->ar_like) > 0)
+ {
+ if (count($this->ar_where) > 0)
+ {
+ $sql .= " AND ";
+ }
+
+ $sql .= implode("\n", $this->ar_like);
+ }
+
+ if (count($this->ar_groupby) > 0)
+ {
+
+ $sql .= "\nGROUP BY ";
+
+ // special consideration for table aliases
+ if (count($this->ar_aliased_tables) > 0 && $this->dbprefix)
+ {
+ $sql .= implode(", ", $this->_filter_table_aliases($this->ar_groupby));
+ }
+ else
+ {
+ $sql .= implode(', ', $this->ar_groupby);
+ }
+ }
+
+ if (count($this->ar_having) > 0)
+ {
+ $sql .= "\nHAVING ";
+ $sql .= implode("\n", $this->ar_having);
+ }
+
+ if (count($this->ar_orderby) > 0)
+ {
+ $sql .= "\nORDER BY ";
+ $sql .= implode(', ', $this->ar_orderby);
+
+ if ($this->ar_order !== FALSE)
+ {
+ $sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';
+ }
+ }
+
+ if (is_numeric($this->ar_limit))
+ {
+ $sql .= "\n";
+ $sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset);
+ }
+
+ return $sql;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Object to Array
+ *
+ * Takes an object as input and converts the class variables to array key/vals
+ *
+ * @access public
+ * @param object
+ * @return array
+ */
+ function _object_to_array($object)
+ {
+ if ( ! is_object($object))
+ {
+ return $object;
+ }
+
+ $array = array();
+ foreach (get_object_vars($object) as $key => $val)
+ {
+ // There are some built in keys we need to ignore for this conversion
+ if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name' && $key != '_ci_scaffolding' && $key != '_ci_scaff_table')
+
+ {
+ $array[$key] = $val;
+ }
+ }
+
+ return $array;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Start Cache
+ *
+ * Starts AR caching
+ *
+ * @access public
+ * @return void
+ */
+ function start_cache()
+ {
+ $this->ar_caching = TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Stop Cache
+ *
+ * Stops AR caching
+ *
+ * @access public
+ * @return void
+ */
+ function stop_cache()
+ {
+ $this->ar_caching = FALSE;
+ }
+
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Flush Cache
+ *
+ * Empties the AR cache
+ *
+ * @access public
+ * @return void
+ */
+ function flush_cache()
+ {
+ $ar_reset_items = array(
+ 'ar_cache_select' => array(),
+ 'ar_cache_from' => array(),
+ 'ar_cache_join' => array(),
+ 'ar_cache_where' => array(),
+ 'ar_cache_like' => array(),
+ 'ar_cache_groupby' => array(),
+ 'ar_cache_having' =>array(),
+ 'ar_cache_orderby' => array(),
+ 'ar_cache_set' => array()
+ );
+
+ $this->_reset_run($ar_reset_items);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Merge Cache
+ *
+ * When called, this function merges any cached AR arrays with
+ * locally called ones.
+ *
+ * @access private
+ * @return void
+ */
+ function _merge_cache()
+ {
+ $ar_items = array('select', 'from', 'join', 'where', 'like', 'groupby', 'having', 'orderby', 'set');
+
+ foreach ($ar_items as $ar_item)
+ {
+ $ar_cache_item = 'ar_cache_'.$ar_item;
+ $ar_item = 'ar_'.$ar_item;
+ $this->$ar_item = array_unique(array_merge($this->$ar_item, $this->$ar_cache_item));
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Resets the active record values. Called by the get() function
+ *
+ * @access private
+ * @param array An array of fields to reset
+ * @return void
+ */
+ function _reset_run($ar_reset_items)
+ {
+ foreach ($ar_reset_items as $item => $default_value)
+ {
+ if (!in_array($item, $this->ar_store_array))
+ {
+ $this->$item = $default_value;
+ }
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Resets the active record values. Called by the get() function
+ *
+ * @access private
+ * @return void
+ */
+ function _reset_select()
+ {
+ $ar_reset_items = array(
+ 'ar_select' => array(),
+ 'ar_from' => array(),
+ 'ar_join' => array(),
+ 'ar_where' => array(),
+ 'ar_like' => array(),
+ 'ar_groupby' => array(),
+ 'ar_having' => array(),
+ 'ar_orderby' => array(),
+ 'ar_wherein' => array(),
+ 'ar_aliased_tables' => array(),
+ 'ar_distinct' => FALSE,
+ 'ar_limit' => FALSE,
+ 'ar_offset' => FALSE,
+ 'ar_order' => FALSE,
+ );
+
+ $this->_reset_run($ar_reset_items);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Resets the active record "write" values.
+ *
+ * Called by the insert() update() and delete() functions
+ *
+ * @access private
+ * @return void
+ */
+ function _reset_write()
+ {
+ $ar_reset_items = array(
+ 'ar_set' => array(),
+ 'ar_from' => array(),
+ 'ar_where' => array(),
+ 'ar_like' => array(),
+ 'ar_orderby' => array(),
+ 'ar_limit' => FALSE,
+ 'ar_order' => FALSE
+ );
+
+ $this->_reset_run($ar_reset_items);
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php
new file mode 100755
index 0000000..ad54fc3
--- /dev/null
+++ b/system/database/DB_cache.php
@@ -0,0 +1,189 @@
+CI
+ // and load the file helper since we use it a lot
+ $this->CI =& get_instance();
+ $this->CI->load->helper('file');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set Cache Directory Path
+ *
+ * @access public
+ * @param string the path to the cache directory
+ * @return bool
+ */
+ function check_path($path = '')
+ {
+ if ($path == '')
+ {
+ if ($this->CI->db->cachedir == '')
+ {
+ return $this->CI->db->cache_off();
+ }
+
+ $path = $this->CI->db->cachedir;
+ }
+
+ // Add a trailing slash to the path if needed
+ $path = preg_replace("/(.+?)\/*$/", "\\1/", $path);
+
+ if ( ! is_dir($path) OR ! is_really_writable($path))
+ {
+ // If the path is wrong we'll turn off caching
+ return $this->CI->db->cache_off();
+ }
+
+ $this->CI->db->cachedir = $path;
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Retrieve a cached query
+ *
+ * The URI being requested will become the name of the cache sub-folder.
+ * An MD5 hash of the SQL statement will become the cache file name
+ *
+ * @access public
+ * @return string
+ */
+ function read($sql)
+ {
+ if ( ! $this->check_path())
+ {
+ return $this->CI->db->cache_off();
+ }
+
+ $uri = ($this->CI->uri->segment(1) == FALSE) ? 'default.' : $this->CI->uri->segment(1).'+';
+ $uri .= ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
+
+ $filepath = $uri.'/'.md5($sql);
+
+ if (FALSE === ($cachedata = read_file($this->CI->db->cachedir.$filepath)))
+ {
+ return FALSE;
+ }
+
+ return unserialize($cachedata);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Write a query to a cache file
+ *
+ * @access public
+ * @return bool
+ */
+ function write($sql, $object)
+ {
+ if ( ! $this->check_path())
+ {
+ return $this->CI->db->cache_off();
+ }
+
+ $uri = ($this->CI->uri->segment(1) == FALSE) ? 'default.' : $this->CI->uri->segment(1).'+';
+ $uri .= ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
+
+ $dir_path = $this->CI->db->cachedir.$uri.'/';
+
+ $filename = md5($sql);
+
+ if ( ! @is_dir($dir_path))
+ {
+ if ( ! @mkdir($dir_path, 0777))
+ {
+ return FALSE;
+ }
+
+ @chmod($dir_path, 0777);
+ }
+
+ if (write_file($dir_path.$filename, serialize($object)) === FALSE)
+ {
+ return FALSE;
+ }
+
+ @chmod($dir_path.$filename, 0777);
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete cache files within a particular directory
+ *
+ * @access public
+ * @return bool
+ */
+ function delete($segment_one = '', $segment_two = '')
+ {
+ if ($segment_one == '')
+ {
+ $segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
+ }
+
+ if ($segment_two == '')
+ {
+ $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
+ }
+
+ $dir_path = $this->CI->db->cachedir.$segment_one.'+'.$segment_two.'/';
+
+ delete_files($dir_path, TRUE);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete all existing cache files
+ *
+ * @access public
+ * @return bool
+ */
+ function delete_all()
+ {
+ delete_files($this->CI->db->cachedir, TRUE);
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
new file mode 100755
index 0000000..b101317
--- /dev/null
+++ b/system/database/DB_driver.php
@@ -0,0 +1,1148 @@
+ $val)
+ {
+ $this->$key = $val;
+ }
+ }
+
+ log_message('debug', 'Database Driver Class Initialized');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Initialize Database Settings
+ *
+ * @access private Called by the constructor
+ * @param mixed
+ * @return void
+ */
+ function initialize($create_db = FALSE)
+ {
+ // If an existing DB connection resource is supplied
+ // there is no need to connect and select the database
+ if (is_resource($this->conn_id))
+ {
+ return TRUE;
+ }
+
+ // Connect to the database
+ $this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect();
+
+ // No connection? Throw an error
+ if ( ! $this->conn_id)
+ {
+ log_message('error', 'Unable to connect to the database');
+
+ if ($this->db_debug)
+ {
+ $this->display_error('db_unable_to_connect');
+ }
+ return FALSE;
+ }
+
+ // Select the database
+ if ($this->database != '')
+ {
+ if ( ! $this->db_select())
+ {
+ // Should we attempt to create the database?
+ if ($create_db == TRUE)
+ {
+ // Load the DB utility class
+ $CI =& get_instance();
+ $CI->load->dbutil();
+
+ // Create the DB
+ if ( ! $CI->dbutil->create_database($this->database))
+ {
+ log_message('error', 'Unable to create database: '.$this->database);
+
+ if ($this->db_debug)
+ {
+ $this->display_error('db_unable_to_create', $this->database);
+ }
+ return FALSE;
+ }
+ else
+ {
+ // In the event the DB was created we need to select it
+ if ($this->db_select())
+ {
+ if (! $this->db_set_charset($this->char_set, $this->dbcollat))
+ {
+ log_message('error', 'Unable to set database connection charset: '.$this->char_set);
+
+ if ($this->db_debug)
+ {
+ $this->display_error('db_unable_to_set_charset', $this->char_set);
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ }
+ }
+
+ log_message('error', 'Unable to select database: '.$this->database);
+
+ if ($this->db_debug)
+ {
+ $this->display_error('db_unable_to_select', $this->database);
+ }
+ return FALSE;
+ }
+
+ if (! $this->db_set_charset($this->char_set, $this->dbcollat))
+ {
+ log_message('error', 'Unable to set database connection charset: '.$this->char_set);
+
+ if ($this->db_debug)
+ {
+ $this->display_error('db_unable_to_set_charset', $this->char_set);
+ }
+
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * The name of the platform in use (mysql, mssql, etc...)
+ *
+ * @access public
+ * @return string
+ */
+ function platform()
+ {
+ return $this->dbdriver;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Database Version Number. Returns a string containing the
+ * version of the database being used
+ *
+ * @access public
+ * @return string
+ */
+ function version()
+ {
+ if (FALSE === ($sql = $this->_version()))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_unsupported_function');
+ }
+ return FALSE;
+ }
+
+ if ($this->dbdriver == 'oci8')
+ {
+ return $sql;
+ }
+
+ $query = $this->query($sql);
+ return $query->row('ver');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Execute the query
+ *
+ * Accepts an SQL string as input and returns a result object upon
+ * successful execution of a "read" type query. Returns boolean TRUE
+ * upon successful execution of a "write" type query. Returns boolean
+ * FALSE upon failure, and if the $db_debug variable is set to TRUE
+ * will raise an error.
+ *
+ * @access public
+ * @param string An SQL query string
+ * @param array An array of binding data
+ * @return mixed
+ */
+ function query($sql, $binds = FALSE, $return_object = TRUE)
+ {
+ if ($sql == '')
+ {
+ if ($this->db_debug)
+ {
+ log_message('error', 'Invalid query: '.$sql);
+ return $this->display_error('db_invalid_query');
+ }
+ return FALSE;
+ }
+
+ // Verify table prefix and replace if necessary
+ if ( ($this->dbprefix != '' AND $this->swap_pre != '') AND ($this->dbprefix != $this->swap_pre) )
+ {
+ $sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql);
+ }
+
+ // Is query caching enabled? If the query is a "read type"
+ // we will load the caching class and return the previously
+ // cached query if it exists
+ if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))
+ {
+ if ($this->_cache_init())
+ {
+ $this->load_rdriver();
+ if (FALSE !== ($cache = $this->CACHE->read($sql)))
+ {
+ return $cache;
+ }
+ }
+ }
+
+ // Compile binds if needed
+ if ($binds !== FALSE)
+ {
+ $sql = $this->compile_binds($sql, $binds);
+ }
+
+ // Save the query for debugging
+ if ($this->save_queries == TRUE)
+ {
+ $this->queries[] = $sql;
+ }
+
+ // Start the Query Timer
+ $time_start = list($sm, $ss) = explode(' ', microtime());
+
+ // Run the Query
+ if (FALSE === ($this->result_id = $this->simple_query($sql)))
+ {
+ // This will trigger a rollback if transactions are being used
+ $this->_trans_status = FALSE;
+
+ if ($this->db_debug)
+ {
+ log_message('error', 'Query error: '.$this->_error_message());
+ return $this->display_error(
+ array(
+ 'Error Number: '.$this->_error_number(),
+ $this->_error_message(),
+ $sql
+ )
+ );
+ }
+
+ return FALSE;
+ }
+
+ // Stop and aggregate the query time results
+ $time_end = list($em, $es) = explode(' ', microtime());
+ $this->benchmark += ($em + $es) - ($sm + $ss);
+
+ if ($this->save_queries == TRUE)
+ {
+ $this->query_times[] = ($em + $es) - ($sm + $ss);
+ }
+
+ // Increment the query counter
+ $this->query_count++;
+
+ // Was the query a "write" type?
+ // If so we'll simply return true
+ if ($this->is_write_type($sql) === TRUE)
+ {
+ // If caching is enabled we'll auto-cleanup any
+ // existing files related to this particular URI
+ if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())
+ {
+ $this->CACHE->delete();
+ }
+
+ return TRUE;
+ }
+
+ // Return TRUE if we don't need to create a result object
+ // Currently only the Oracle driver uses this when stored
+ // procedures are used
+ if ($return_object !== TRUE)
+ {
+ return TRUE;
+ }
+
+ // Load and instantiate the result driver
+
+ $driver = $this->load_rdriver();
+ $RES = new $driver();
+ $RES->conn_id = $this->conn_id;
+ $RES->result_id = $this->result_id;
+ $RES->num_rows = $RES->num_rows();
+
+ if ($this->dbdriver == 'oci8')
+ {
+ $RES->stmt_id = $this->stmt_id;
+ $RES->curs_id = NULL;
+ $RES->limit_used = $this->limit_used;
+ }
+
+ // Is query caching enabled? If so, we'll serialize the
+ // result object and save it to a cache file.
+ if ($this->cache_on == TRUE AND $this->_cache_init())
+ {
+ // We'll create a new instance of the result object
+ // only without the platform specific driver since
+ // we can't use it with cached data (the query result
+ // resource ID won't be any good once we've cached the
+ // result object, so we'll have to compile the data
+ // and save it)
+ $CR = new CI_DB_result();
+ $CR->num_rows = $RES->num_rows();
+ $CR->result_object = $RES->result_object();
+ $CR->result_array = $RES->result_array();
+
+ // Reset these since cached objects can not utilize resource IDs.
+ $CR->conn_id = NULL;
+ $CR->result_id = NULL;
+
+ $this->CACHE->write($sql, $CR);
+ }
+
+ return $RES;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Load the result drivers
+ *
+ * @access public
+ * @return string the name of the result class
+ */
+ function load_rdriver()
+ {
+ $driver = 'CI_DB_'.$this->dbdriver.'_result';
+
+ if ( ! class_exists($driver))
+ {
+ include_once(BASEPATH.'database/DB_result'.EXT);
+ include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT);
+ }
+
+ return $driver;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Simple Query
+ * This is a simplified version of the query() function. Internally
+ * we only use it when running transaction commands since they do
+ * not require all the features of the main query() function.
+ *
+ * @access public
+ * @param string the sql query
+ * @return mixed
+ */
+ function simple_query($sql)
+ {
+ if ( ! $this->conn_id)
+ {
+ $this->initialize();
+ }
+
+ return $this->_execute($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Disable Transactions
+ * This permits transactions to be disabled at run-time.
+ *
+ * @access public
+ * @return void
+ */
+ function trans_off()
+ {
+ $this->trans_enabled = FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Start Transaction
+ *
+ * @access public
+ * @return void
+ */
+ function trans_start($test_mode = FALSE)
+ {
+ if ( ! $this->trans_enabled)
+ {
+ return FALSE;
+ }
+
+ // When transactions are nested we only begin/commit/rollback the outermost ones
+ if ($this->_trans_depth > 0)
+ {
+ $this->_trans_depth += 1;
+ return;
+ }
+
+ $this->trans_begin($test_mode);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Complete Transaction
+ *
+ * @access public
+ * @return bool
+ */
+ function trans_complete()
+ {
+ if ( ! $this->trans_enabled)
+ {
+ return FALSE;
+ }
+
+ // When transactions are nested we only begin/commit/rollback the outermost ones
+ if ($this->_trans_depth > 1)
+ {
+ $this->_trans_depth -= 1;
+ return TRUE;
+ }
+
+ // The query() function will set this flag to TRUE in the event that a query failed
+ if ($this->_trans_status === FALSE)
+ {
+ $this->trans_rollback();
+
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_transaction_failure');
+ }
+ return FALSE;
+ }
+
+ $this->trans_commit();
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Lets you retrieve the transaction flag to determine if it has failed
+ *
+ * @access public
+ * @return bool
+ */
+ function trans_status()
+ {
+ return $this->_trans_status;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Compile Bindings
+ *
+ * @access public
+ * @param string the sql statement
+ * @param array an array of bind data
+ * @return string
+ */
+ function compile_binds($sql, $binds)
+ {
+ if (strpos($sql, $this->bind_marker) === FALSE)
+ {
+ return $sql;
+ }
+
+ if ( ! is_array($binds))
+ {
+ $binds = array($binds);
+ }
+
+ // Get the sql segments around the bind markers
+ $segments = explode($this->bind_marker, $sql);
+
+ // The count of bind should be 1 less then the count of segments
+ // If there are more bind arguments trim it down
+ if (count($binds) >= count($segments)) {
+ $binds = array_slice($binds, 0, count($segments)-1);
+ }
+
+ // Construct the binded query
+ $result = $segments[0];
+ $i = 0;
+ foreach ($binds as $bind)
+ {
+ $result .= $this->escape($bind);
+ $result .= $segments[++$i];
+ }
+
+ return $result;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Determines if a query is a "write" type.
+ *
+ * @access public
+ * @param string An SQL query string
+ * @return boolean
+ */
+ function is_write_type($sql)
+ {
+ if ( ! preg_match('/^\s*"?(INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql))
+ {
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Calculate the aggregate query elapsed time
+ *
+ * @access public
+ * @param integer The number of decimal places
+ * @return integer
+ */
+ function elapsed_time($decimals = 6)
+ {
+ return number_format($this->benchmark, $decimals);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the total number of queries
+ *
+ * @access public
+ * @return integer
+ */
+ function total_queries()
+ {
+ return $this->query_count;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the last query that was executed
+ *
+ * @access public
+ * @return void
+ */
+ function last_query()
+ {
+ return end($this->queries);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Protect Identifiers
+ *
+ * This function adds backticks if appropriate based on db type
+ *
+ * @access private
+ * @param mixed the item to escape
+ * @param boolean only affect the first word
+ * @return mixed the item with backticks
+ */
+ function protect_identifiers($item, $first_word_only = FALSE)
+ {
+ return $this->_protect_identifiers($item, $first_word_only);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * "Smart" Escape String
+ *
+ * Escapes data based on type
+ * Sets boolean and null types
+ *
+ * @access public
+ * @param string
+ * @return integer
+ */
+ function escape($str)
+ {
+ switch (gettype($str))
+ {
+ case 'string' : $str = "'".$this->escape_str($str)."'";
+ break;
+ case 'boolean' : $str = ($str === FALSE) ? 0 : 1;
+ break;
+ default : $str = ($str === NULL) ? 'NULL' : $str;
+ break;
+ }
+
+ return $str;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Primary
+ *
+ * Retrieves the primary key. It assumes that the row in the first
+ * position is the primary key
+ *
+ * @access public
+ * @param string the table name
+ * @return string
+ */
+ function primary($table = '')
+ {
+ $fields = $this->list_fields($table);
+
+ if ( ! is_array($fields))
+ {
+ return FALSE;
+ }
+
+ return current($fields);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns an array of table names
+ *
+ * @access public
+ * @return array
+ */
+ function list_tables($constrain_by_prefix = FALSE)
+ {
+ // Is there a cached result?
+ if (isset($this->data_cache['table_names']))
+ {
+ return $this->data_cache['table_names'];
+ }
+
+ if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix)))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_unsupported_function');
+ }
+ return FALSE;
+ }
+
+ $retval = array();
+ $query = $this->query($sql);
+
+ if ($query->num_rows() > 0)
+ {
+ foreach($query->result_array() as $row)
+ {
+ if (isset($row['TABLE_NAME']))
+ {
+ $retval[] = $row['TABLE_NAME'];
+ }
+ else
+ {
+ $retval[] = array_shift($row);
+ }
+ }
+ }
+
+ $this->data_cache['table_names'] = $retval;
+ return $this->data_cache['table_names'];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Determine if a particular table exists
+ * @access public
+ * @return boolean
+ */
+ function table_exists($table_name)
+ {
+ return ( ! in_array($this->prep_tablename($table_name), $this->list_tables())) ? FALSE : TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch MySQL Field Names
+ *
+ * @access public
+ * @param string the table name
+ * @return array
+ */
+ function list_fields($table = '')
+ {
+ // Is there a cached result?
+ if (isset($this->data_cache['field_names'][$table]))
+ {
+ return $this->data_cache['field_names'][$table];
+ }
+
+ if ($table == '')
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_field_param_missing');
+ }
+ return FALSE;
+ }
+
+ if (FALSE === ($sql = $this->_list_columns($this->prep_tablename($table))))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_unsupported_function');
+ }
+ return FALSE;
+ }
+
+ $query = $this->query($sql);
+
+ $retval = array();
+ foreach($query->result_array() as $row)
+ {
+ if (isset($row['COLUMN_NAME']))
+ {
+ $retval[] = $row['COLUMN_NAME'];
+ }
+ else
+ {
+ $retval[] = current($row);
+ }
+ }
+
+ $this->data_cache['field_names'][$table] = $retval;
+ return $this->data_cache['field_names'][$table];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Determine if a particular field exists
+ * @access public
+ * @param string
+ * @param string
+ * @return boolean
+ */
+ function field_exists($field_name, $table_name)
+ {
+ return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * DEPRECATED - use list_fields()
+ */
+ function field_names($table = '')
+ {
+ return $this->list_fields($table);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns an object with field data
+ *
+ * @access public
+ * @param string the table name
+ * @return object
+ */
+ function field_data($table = '')
+ {
+ if ($table == '')
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_field_param_missing');
+ }
+ return FALSE;
+ }
+
+ $query = $this->query($this->_field_data($this->prep_tablename($table)));
+ return $query->field_data();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Generate an insert string
+ *
+ * @access public
+ * @param string the table upon which the query will be performed
+ * @param array an associative array data of key/values
+ * @return string
+ */
+ function insert_string($table, $data)
+ {
+ $fields = array();
+ $values = array();
+
+ foreach($data as $key => $val)
+ {
+ $fields[] = $key;
+ $values[] = $this->escape($val);
+ }
+
+
+ return $this->_insert($this->prep_tablename($table), $fields, $values);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Generate an update string
+ *
+ * @access public
+ * @param string the table upon which the query will be performed
+ * @param array an associative array data of key/values
+ * @param mixed the "where" statement
+ * @return string
+ */
+ function update_string($table, $data, $where)
+ {
+ if ($where == '')
+ return false;
+
+ $fields = array();
+ foreach($data as $key => $val)
+ {
+ $fields[$key] = $this->escape($val);
+ }
+
+ if ( ! is_array($where))
+ {
+ $dest = array($where);
+ }
+ else
+ {
+ $dest = array();
+ foreach ($where as $key => $val)
+ {
+ $prefix = (count($dest) == 0) ? '' : ' AND ';
+
+ if ($val !== '')
+ {
+ if ( ! $this->_has_operator($key))
+ {
+ $key .= ' =';
+ }
+
+ $val = ' '.$this->escape($val);
+ }
+
+ $dest[] = $prefix.$key.$val;
+ }
+ }
+
+ return $this->_update($this->prep_tablename($table), $fields, $dest);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Prep the table name - simply adds the table prefix if needed
+ *
+ * @access public
+ * @param string the table name
+ * @return string
+ */
+ function prep_tablename($table = '')
+ {
+ // Do we need to add the table prefix?
+ if ($this->dbprefix != '')
+ {
+ if (substr($table, 0, strlen($this->dbprefix)) != $this->dbprefix)
+ {
+ $table = $this->dbprefix.$table;
+ }
+ }
+
+ return $table;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Enables a native PHP function to be run, using a platform agnostic wrapper.
+ *
+ * @access public
+ * @param string the function name
+ * @param mixed any parameters needed by the function
+ * @return mixed
+ */
+ function call_function($function)
+ {
+ $driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';
+
+ if (FALSE === strpos($driver, $function))
+ {
+ $function = $driver.$function;
+ }
+
+ if ( ! function_exists($function))
+ {
+ if ($this->db_debug)
+ {
+ return $this->display_error('db_unsupported_function');
+ }
+ return FALSE;
+ }
+ else
+ {
+ $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;
+
+ return call_user_func_array($function, $args);
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set Cache Directory Path
+ *
+ * @access public
+ * @param string the path to the cache directory
+ * @return void
+ */
+ function cache_set_path($path = '')
+ {
+ $this->cachedir = $path;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Enable Query Caching
+ *
+ * @access public
+ * @return void
+ */
+ function cache_on()
+ {
+ $this->cache_on = TRUE;
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Disable Query Caching
+ *
+ * @access public
+ * @return void
+ */
+ function cache_off()
+ {
+ $this->cache_on = FALSE;
+ return FALSE;
+ }
+
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete the cache files associated with a particular URI
+ *
+ * @access public
+ * @return void
+ */
+ function cache_delete($segment_one = '', $segment_two = '')
+ {
+ if ( ! $this->_cache_init())
+ {
+ return FALSE;
+ }
+ return $this->CACHE->delete($segment_one, $segment_two);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Delete All cache files
+ *
+ * @access public
+ * @return void
+ */
+ function cache_delete_all()
+ {
+ if ( ! $this->_cache_init())
+ {
+ return FALSE;
+ }
+
+ return $this->CACHE->delete_all();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Initialize the Cache Class
+ *
+ * @access private
+ * @return void
+ */
+ function _cache_init()
+ {
+ if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))
+ {
+ return TRUE;
+ }
+
+ if ( ! @include(BASEPATH.'database/DB_cache'.EXT))
+ {
+ return $this->cache_off();
+ }
+
+ $this->CACHE = new CI_DB_Cache;
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Close DB Connection
+ *
+ * @access public
+ * @return void
+ */
+ function close()
+ {
+ if (is_resource($this->conn_id))
+ {
+ $this->_close($this->conn_id);
+ }
+ $this->conn_id = FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Display an error message
+ *
+ * @access public
+ * @param string the error message
+ * @param string any "swap" values
+ * @param boolean whether to localize the message
+ * @return string sends the application/error_db.php template
+ */
+ function display_error($error = '', $swap = '', $native = FALSE)
+ {
+// $LANG = new CI_Lang();
+ $LANG = new CI_Language();
+ $LANG->load('db');
+
+ $heading = 'Database Error';
+
+ if ($native == TRUE)
+ {
+ $message = $error;
+ }
+ else
+ {
+ $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;
+ }
+
+ if ( ! class_exists('CI_Exceptions'))
+ {
+// include(BASEPATH.'core/Exceptions'.EXT);
+ include(BASEPATH.'libraries/Exceptions'.EXT);
+ }
+
+ $error = new CI_Exceptions();
+ echo $error->show_error('An Error Was Encountered', $message, 'error_db');
+ exit;
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
new file mode 100755
index 0000000..cd468bc
--- /dev/null
+++ b/system/database/DB_forge.php
@@ -0,0 +1,322 @@
+db
+ $CI =& get_instance();
+ $this->db =& $CI->db;
+ log_message('debug', "Database Forge Class Initialized");
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Create database
+ *
+ * @access public
+ * @param string the database name
+ * @return bool
+ */
+ function create_database($db_name)
+ {
+ $sql = $this->_create_database($db_name);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Drop database
+ *
+ * @access public
+ * @param string the database name
+ * @return bool
+ */
+ function drop_database($db_name)
+ {
+ $sql = $this->_drop_database($db_name);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Add Key
+ *
+ * @access public
+ * @param string key
+ * @param string type
+ * @return void
+ */
+ function add_key($key = '', $primary = FALSE)
+ {
+ if ($key == '')
+ {
+ show_error('Key information is required for that operation.');
+ }
+
+ if ($primary === TRUE)
+ {
+ $this->primary_keys[] = $key;
+ }
+ else
+ {
+ $this->keys[] = $key;
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Add Field
+ *
+ * @access public
+ * @param string collation
+ * @return void
+ */
+ function add_field($field = '')
+ {
+ if ($field == '')
+ {
+ show_error('Field information is required.');
+ }
+
+ if (is_string($field))
+ {
+ if ($field == 'id')
+ {
+ $this->fields[] = array('id' => array(
+ 'type' => 'INT',
+ 'constraint' => 9,
+ 'auto_increment' => TRUE
+ )
+ );
+ $this->add_key('id', TRUE);
+ }
+ else
+ {
+ if (strpos($field, ' ') === FALSE)
+ {
+ show_error('Field information is required for that operation.');
+ }
+
+ $this->fields[] = $field;
+ }
+ }
+
+ if (is_array($field))
+ {
+ $this->fields = array_merge($this->fields, $field);
+ }
+
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Create Table
+ *
+ * @access public
+ * @param string the table name
+ * @return bool
+ */
+ function create_table($table = '', $if_not_exists = FALSE)
+ {
+ if ($table == '')
+ {
+ show_error('A table name is required for that operation.');
+ }
+
+ if (count($this->fields) == 0)
+ {
+ show_error('Field information is required.');
+ }
+
+ $sql = $this->_create_table($this->db->dbprefix.$table, $this->fields, $this->primary_keys, $this->keys, $if_not_exists);
+
+ $this->_reset();
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Drop Table
+ *
+ * @access public
+ * @param string the table name
+ * @return bool
+ */
+ function drop_table($table_name)
+ {
+ $sql = $this->_drop_table($this->db->dbprefix.$table_name);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Column Add
+ *
+ * @access public
+ * @param string the table name
+ * @param string the column name
+ * @param string the column definition
+ * @return bool
+ */
+ function add_column($table = '', $field = array(), $after_field = '')
+ {
+ if ($table == '')
+ {
+ show_error('A table name is required for that operation.');
+ }
+
+ // add field info into field array, but we can only do one at a time
+ // so only grab the first field in the event there are more then one
+ $this->add_field(array_slice($field, 0, 1));
+
+ if (count($this->fields) == 0)
+ {
+ show_error('Field information is required.');
+ }
+
+ $sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field);
+
+ $this->_reset();
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Column Drop
+ *
+ * @access public
+ * @param string the table name
+ * @param string the column name
+ * @return bool
+ */
+ function drop_column($table = '', $column_name = '')
+ {
+
+ if ($table == '')
+ {
+ show_error('A table name is required for that operation.');
+ }
+
+ if ($column_name == '')
+ {
+ show_error('A column name is required for that operation.');
+ }
+
+ $sql = $this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name);
+
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Column Modify
+ *
+ * @access public
+ * @param string the table name
+ * @param string the column name
+ * @param string the column definition
+ * @return bool
+ */
+ function modify_column($table = '', $field = array())
+ {
+
+ if ($table == '')
+ {
+ show_error('A table name is required for that operation.');
+ }
+
+ // add field info into field array, but we can only do one at a time
+ // so only grab the first field in the event there are more then one
+ $this->add_field(array_slice($field, 0, 1));
+
+ if (count($this->fields) == 0)
+ {
+ show_error('Field information is required.');
+ }
+
+ $sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields);
+
+ $this->_reset();
+ return $this->db->query($sql);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Reset
+ *
+ * Resets table creation vars
+ *
+ * @access private
+ * @return void
+ */
+ function _reset()
+ {
+ $this->fields = array();
+ $this->keys = array();
+ $this->primary_keys = array();
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/system/database/DB_result.php b/system/database/DB_result.php
new file mode 100755
index 0000000..7d50979
--- /dev/null
+++ b/system/database/DB_result.php
@@ -0,0 +1,340 @@
+result_object() : $this->result_array();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Query result. "object" version.
+ *
+ * @access public
+ * @return object
+ */
+ function result_object()
+ {
+ if (count($this->result_object) > 0)
+ {
+ return $this->result_object;
+ }
+
+ // In the event that query caching is on the result_id variable
+ // will return FALSE since there isn't a valid SQL resource so
+ // we'll simply return an empty array.
+ if ($this->result_id === FALSE OR $this->num_rows() == 0)
+ {
+ return array();
+ }
+
+ $this->_data_seek(0);
+ while ($row = $this->_fetch_object())
+ {
+ $this->result_object[] = $row;
+ }
+
+ return $this->result_object;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Query result. "array" version.
+ *
+ * @access public
+ * @return array
+ */
+ function result_array()
+ {
+ if (count($this->result_array) > 0)
+ {
+ return $this->result_array;
+ }
+
+ // In the event that query caching is on the result_id variable
+ // will return FALSE since there isn't a valid SQL resource so
+ // we'll simply return an empty array.
+ if ($this->result_id === FALSE OR $this->num_rows() == 0)
+ {
+ return array();
+ }
+
+ $this->_data_seek(0);
+ while ($row = $this->_fetch_assoc())
+ {
+ $this->result_array[] = $row;
+ }
+
+ return $this->result_array;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Query result. Acts as a wrapper function for the following functions.
+ *
+ * @access public
+ * @param string
+ * @param string can be "object" or "array"
+ * @return mixed either a result object or array
+ */
+ function row($n = 0, $type = 'object')
+ {
+ if ( ! is_numeric($n))
+ {
+ // We cache the row data for subsequent uses
+ if ( ! is_array($this->row_data))
+ {
+ $this->row_data = $this->row_array(0);
+ }
+
+ if (isset($this->row_data[$n]))
+ {
+ return $this->row_data[$n];
+ }
+ // reset the $n variable if the result was not achieved
+ $n = 0;
+ }
+
+ return ($type == 'object') ? $this->row_object($n) : $this->row_array($n);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Assigns an item into a particular column slot
+ *
+ * @access public
+ * @return object
+ */
+ function set_row($key, $value = NULL)
+ {
+ // We cache the row data for subsequent uses
+ if ( ! is_array($this->row_data))
+ {
+ $this->row_data = $this->row_array(0);
+ }
+
+ if (is_array($key))
+ {
+ foreach ($key as $k => $v)
+ {
+ $this->row_data[$k] = $v;
+ }
+
+ return;
+ }
+
+ if ($key != '' AND ! is_null($value))
+ {
+ $this->row_data[$key] = $value;
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns a single result row - object version
+ *
+ * @access public
+ * @return object
+ */
+ function row_object($n = 0)
+ {
+ $result = $this->result_object();
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+
+ if ($n != $this->current_row AND isset($result[$n]))
+ {
+ $this->current_row = $n;
+ }
+
+ return $result[$this->current_row];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns a single result row - array version
+ *
+ * @access public
+ * @return array
+ */
+ function row_array($n = 0)
+ {
+ $result = $this->result_array();
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+
+ if ($n != $this->current_row AND isset($result[$n]))
+ {
+ $this->current_row = $n;
+ }
+
+ return $result[$this->current_row];
+ }
+
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the "first" row
+ *
+ * @access public
+ * @return object
+ */
+ function first_row($type = 'object')
+ {
+ $result = $this->result($type);
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+ return $result[0];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the "last" row
+ *
+ * @access public
+ * @return object
+ */
+ function last_row($type = 'object')
+ {
+ $result = $this->result($type);
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+ return $result[count($result) -1];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the "next" row
+ *
+ * @access public
+ * @return object
+ */
+ function next_row($type = 'object')
+ {
+ $result = $this->result($type);
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+
+ if (isset($result[$this->current_row + 1]))
+ {
+ ++$this->current_row;
+ }
+
+ return $result[$this->current_row];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Returns the "previous" row
+ *
+ * @access public
+ * @return object
+ */
+ function previous_row($type = 'object')
+ {
+ $result = $this->result($type);
+
+ if (count($result) == 0)
+ {
+ return $result;
+ }
+
+ if (isset($result[$this->current_row - 1]))
+ {
+ --$this->current_row;
+ }
+ return $result[$this->current_row];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * The following functions are normally overloaded by the identically named
+ * methods in the platform-specific driver -- except when query caching
+ * is used. When caching is enabled we do not load the other driver.
+ * These functions are primarily here to prevent undefined function errors
+ * when a cached result object is in use. They are not otherwise fully
+ * operational due to the unavailability of the database resource IDs with
+ * cached results.
+ */
+ function num_rows() { return $this->num_rows; }
+ function num_fields() { return 0; }
+ function list_fields() { return array(); }
+ function field_names() { return array(); } // Deprecated
+ function field_data() { return array(); }
+ function free_result() { return TRUE; }
+ function _data_seek() { return TRUE; }
+ function _fetch_assoc() { return array(); }
+ function _fetch_object() { return array(); }
+
+}
+// END DB_result class
+?>
\ No newline at end of file
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
new file mode 100755
index 0000000..d9b8fed
--- /dev/null
+++ b/system/database/DB_utility.php
@@ -0,0 +1,387 @@
+db
+ $CI =& get_instance();
+ $this->db =& $CI->db;
+
+ log_message('debug', "Database Utility Class Initialized");
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * List databases
+ *
+ * @access public
+ * @return bool
+ */
+ function list_databases()
+ {
+ // Is there a cached result?
+ if (isset($this->data_cache['db_names']))
+ {
+ return $this->data_cache['db_names'];
+ }
+
+ $query = $this->db->query($this->_list_databases());
+ $dbs = array();
+ if ($query->num_rows() > 0)
+ {
+ foreach ($query->result_array() as $row)
+ {
+ $dbs[] = current($row);
+ }
+ }
+
+ $this->data_cache['db_names'] = $dbs;
+ return $this->data_cache['db_names'];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Optimize Table
+ *
+ * @access public
+ * @param string the table name
+ * @return bool
+ */
+ function optimize_table($table_name)
+ {
+ $sql = $this->_optimize_table($table_name);
+
+ if (is_bool($sql))
+ {
+ show_error('db_must_use_set');
+ }
+
+ $query = $this->db->query($sql);
+ $res = $query->result_array();
+
+ // Note: Due to a bug in current() that affects some versions
+ // of PHP we can not pass function call directly into it
+ return current($res);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Optimize Database
+ *
+ * @access public
+ * @return array
+ */
+ function optimize_database()
+ {
+ $result = array();
+ foreach ($this->db->list_tables() as $table_name)
+ {
+ $sql = $this->_optimize_table($table_name);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ $query = $this->db->query($sql);
+
+ // Build the result array...
+ // Note: Due to a bug in current() that affects some versions
+ // of PHP we can not pass function call directly into it
+ $res = $query->result_array();
+ $res = current($res);
+ $key = str_replace($this->db->database.'.', '', current($res));
+ $keys = array_keys($res);
+ unset($res[$keys[0]]);
+
+ $result[$key] = $res;
+ }
+
+ return $result;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Repair Table
+ *
+ * @access public
+ * @param string the table name
+ * @return bool
+ */
+ function repair_table($table_name)
+ {
+ $sql = $this->_repair_table($table_name);
+
+ if (is_bool($sql))
+ {
+ return $sql;
+ }
+
+ $query = $this->db->query($sql);
+
+ // Note: Due to a bug in current() that affects some versions
+ // of PHP we can not pass function call directly into it
+ $res = $query->result_array();
+ return current($res);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Generate CSV from a query result object
+ *
+ * @access public
+ * @param object The query result object
+ * @param string The delimiter - comma by default
+ * @param string The newline character - \n by default
+ * @param string The enclosure - double quote by default
+ * @return string
+ */
+ function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"')
+ {
+ if ( ! is_object($query) OR ! method_exists($query, 'field_names'))
+ {
+ show_error('You must submit a valid result object');
+ }
+
+ $out = '';
+
+ // First generate the headings from the table column names
+ foreach ($query->list_fields() as $name)
+ {
+ $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
+ }
+
+ $out = rtrim($out);
+ $out .= $newline;
+
+ // Next blast through the result array and build out the rows
+ foreach ($query->result_array() as $row)
+ {
+ foreach ($row as $item)
+ {
+ $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;
+ }
+ $out = rtrim($out);
+ $out .= $newline;
+ }
+
+ return $out;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Generate XML data from a query result object
+ *
+ * @access public
+ * @param object The query result object
+ * @param array Any preferences
+ * @return string
+ */
+ function xml_from_result($query, $params = array())
+ {
+ if ( ! is_object($query) OR ! method_exists($query, 'field_names'))
+ {
+ show_error('You must submit a valid result object');
+ }
+
+ // Set our default values
+ foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
+ {
+ if ( ! isset($params[$key]))
+ {
+ $params[$key] = $val;
+ }
+ }
+
+ // Create variables for convenience
+ extract($params);
+
+ // Load the xml helper
+ $CI =& get_instance();
+ $CI->load->helper('xml');
+
+ // Generate the result
+ $xml = "<{$root}>".$newline;
+ foreach ($query->result_array() as $row)
+ {
+ $xml .= $tab."<{$element}>".$newline;
+
+ foreach ($row as $key => $val)
+ {
+ $xml .= $tab.$tab."<{$key}>".xml_convert($val)."{$key}>".$newline;
+ }
+ $xml .= $tab."{$element}>".$newline;
+ }
+ $xml .= "$root>".$newline;
+
+ return $xml;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Database Backup
+ *
+ * @access public
+ * @return void
+ */
+ function backup($params = array())
+ {
+ // If the parameters have not been submitted as an
+ // array then we know that it is simply the table
+ // name, which is a valid short cut.
+ if (is_string($params))
+ {
+ $params = array('tables' => $params);
+ }
+
+ // ------------------------------------------------------
+
+ // Set up our default preferences
+ $prefs = array(
+ 'tables' => array(),
+ 'ignore' => array(),
+ 'filename' => '',
+ 'format' => 'gzip', // gzip, zip, txt
+ 'add_drop' => TRUE,
+ 'add_insert' => TRUE,
+ 'newline' => "\n"
+ );
+
+ // Did the user submit any preferences? If so set them....
+ if (count($params) > 0)
+ {
+ foreach ($prefs as $key => $val)
+ {
+ if (isset($params[$key]))
+ {
+ $prefs[$key] = $params[$key];
+ }
+ }
+ }
+
+ // ------------------------------------------------------
+
+ // Are we backing up a complete database or individual tables?
+ // If no table names were submitted we'll fetch the entire table list
+ if (count($prefs['tables']) == 0)
+ {
+ $prefs['tables'] = $this->db->list_tables();
+ }
+
+ // ------------------------------------------------------
+
+ // Validate the format
+ if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
+ {
+ $prefs['format'] = 'txt';
+ }
+
+ // ------------------------------------------------------
+
+ // Is the encoder supported? If not, we'll either issue an
+ // error or use plain text depending on the debug settings
+ if (($prefs['format'] == 'gzip' AND ! @function_exists('gzencode'))
+ OR ($prefs['format'] == 'zip' AND ! @function_exists('gzcompress')))
+ {
+ if ($this->db->db_debug)
+ {
+ return $this->db->display_error('db_unsuported_compression');
+ }
+
+ $prefs['format'] = 'txt';
+ }
+
+ // ------------------------------------------------------
+
+ // Set the filename if not provided - Only needed with Zip files
+ if ($prefs['filename'] == '' AND $prefs['format'] == 'zip')
+ {
+ $prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database;
+ $prefs['filename'] .= '_'.date('Y-m-d_H-i', time());
+ }
+
+ // ------------------------------------------------------
+
+ // Was a Gzip file requested?
+ if ($prefs['format'] == 'gzip')
+ {
+ return gzencode($this->_backup($prefs));
+ }
+
+ // ------------------------------------------------------
+
+ // Was a text file requested?
+ if ($prefs['format'] == 'txt')
+ {
+ return $this->_backup($prefs);
+ }
+
+ // ------------------------------------------------------
+
+ // Was a Zip file requested?
+ if ($prefs['format'] == 'zip')
+ {
+ // If they included the .zip file extension we'll remove it
+ if (preg_match("|.+?\.zip$|", $prefs['filename']))
+ {
+ $prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
+ }
+
+ // Tack on the ".sql" file extension if needed
+ if ( ! preg_match("|.+?\.sql$|", $prefs['filename']))
+ {
+ $prefs['filename'] .= '.sql';
+ }
+
+ // Load the Zip class and output it
+
+ $CI =& get_instance();
+ $CI->load->library('zip');
+ $CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
+ return $CI->zip->get_zip();
+ }
+
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/system/database/drivers/.svn/all-wcprops b/system/database/drivers/.svn/all-wcprops
new file mode 100644
index 0000000..fa266be
--- /dev/null
+++ b/system/database/drivers/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 46
+/svn/!svn/ver/18/trunk/system/database/drivers
+END
+index.html
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/svn/!svn/ver/18/trunk/system/database/drivers/index.html
+END
diff --git a/system/database/drivers/.svn/entries b/system/database/drivers/.svn/entries
new file mode 100644
index 0000000..3a2a439
--- /dev/null
+++ b/system/database/drivers/.svn/entries
@@ -0,0 +1,83 @@
+10
+
+dir
+124
+http://sweetcron.googlecode.com/svn/trunk/system/database/drivers
+http://sweetcron.googlecode.com/svn
+
+
+
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+51b50d7d-0b4b-0410-974b-f188aa86c7d9
+
+mssql
+dir
+
+sqlite
+dir
+
+oci8
+dir
+
+postgre
+dir
+
+mysql
+dir
+
+odbc
+dir
+
+index.html
+file
+
+
+
+
+2009-09-15T00:18:11.000000Z
+362a648cc43551584abe596372cb8da8
+2008-08-28T06:03:25.654136Z
+18
+yongfook
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+149
+
+mysqli
+dir
+
diff --git a/system/database/drivers/.svn/prop-base/index.html.svn-base b/system/database/drivers/.svn/prop-base/index.html.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/system/database/drivers/.svn/prop-base/index.html.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/system/database/drivers/.svn/text-base/index.html.svn-base b/system/database/drivers/.svn/text-base/index.html.svn-base
new file mode 100644
index 0000000..5a1f5d6
--- /dev/null
+++ b/system/database/drivers/.svn/text-base/index.html.svn-base
@@ -0,0 +1,15 @@
+
+
+
+
+403 Forbidden
+
+
+
+
+
+
Directory access is forbidden.
+
+
+
+
\ No newline at end of file
diff --git a/system/database/drivers/index.html b/system/database/drivers/index.html
new file mode 100755
index 0000000..5a1f5d6
--- /dev/null
+++ b/system/database/drivers/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/system/helpers/.svn/text-base/inflector_helper.php.svn-base b/system/helpers/.svn/text-base/inflector_helper.php.svn-base
new file mode 100644
index 0000000..bf70a67
--- /dev/null
+++ b/system/helpers/.svn/text-base/inflector_helper.php.svn-base
@@ -0,0 +1,167 @@
+
\ No newline at end of file
diff --git a/system/helpers/.svn/text-base/path_helper.php.svn-base b/system/helpers/.svn/text-base/path_helper.php.svn-base
new file mode 100644
index 0000000..30d26d6
--- /dev/null
+++ b/system/helpers/.svn/text-base/path_helper.php.svn-base
@@ -0,0 +1,70 @@
+
\ No newline at end of file
diff --git a/system/helpers/.svn/text-base/security_helper.php.svn-base b/system/helpers/.svn/text-base/security_helper.php.svn-base
new file mode 100644
index 0000000..7552fd8
--- /dev/null
+++ b/system/helpers/.svn/text-base/security_helper.php.svn-base
@@ -0,0 +1,124 @@
+input->xss_clean($str, $charset);
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Hash encode a string
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('dohash'))
+{
+ function dohash($str, $type = 'sha1')
+ {
+ if ($type == 'sha1')
+ {
+ if ( ! function_exists('sha1'))
+ {
+ if ( ! function_exists('mhash'))
+ {
+ require_once(BASEPATH.'libraries/Sha1'.EXT);
+ $SH = new CI_SHA;
+ return $SH->generate($str);
+ }
+ else
+ {
+ return bin2hex(mhash(MHASH_SHA1, $str));
+ }
+ }
+ else
+ {
+ return sha1($str);
+ }
+ }
+ else
+ {
+ return md5($str);
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Strip Image Tags
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('strip_image_tags'))
+{
+ function strip_image_tags($str)
+ {
+ $str = preg_replace("##", "\\1", $str);
+ $str = preg_replace("##", "\\1", $str);
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Convert PHP tags to entities
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('encode_php_tags'))
+{
+ function encode_php_tags($str)
+ {
+ return str_replace(array(''), array('<?php', '<?PHP', '<?', '?>'), $str);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/system/helpers/.svn/text-base/smiley_helper.php.svn-base b/system/helpers/.svn/text-base/smiley_helper.php.svn-base
new file mode 100644
index 0000000..25962eb
--- /dev/null
+++ b/system/helpers/.svn/text-base/smiley_helper.php.svn-base
@@ -0,0 +1,173 @@
+
+ function insert_smiley(smiley)
+ {
+ document.{$form_name}.{$form_field}.value += " " + smiley;
+ }
+
+EOF;
+ }
+}
+// ------------------------------------------------------------------------
+
+/**
+ * Get Clickable Smileys
+ *
+ * Returns an array of image tag links that can be clicked to be inserted
+ * into a form field.
+ *
+ * @access public
+ * @param string the URL to the folder containing the smiley images
+ * @return array
+ */
+if (! function_exists('get_clickable_smileys'))
+{
+ function get_clickable_smileys($image_url = '', $smileys = NULL)
+ {
+ if ( ! is_array($smileys))
+ {
+ if (FALSE === ($smileys = _get_smiley_array()))
+ {
+ return $smileys;
+ }
+ }
+
+ // Add a trailing slash to the file path if needed
+ $image_url = preg_replace("/(.+?)\/*$/", "\\1/", $image_url);
+
+ $used = array();
+ foreach ($smileys as $key => $val)
+ {
+ // Keep duplicates from being used, which can happen if the
+ // mapping array contains multiple identical replacements. For example:
+ // :-) and :) might be replaced with the same image so both smileys
+ // will be in the array.
+ if (isset($used[$smileys[$key][0]]))
+ {
+ continue;
+ }
+
+ $link[] = "";
+
+ $used[$smileys[$key][0]] = TRUE;
+ }
+
+ return $link;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Parse Smileys
+ *
+ * Takes a string as input and swaps any contained smileys for the actual image
+ *
+ * @access public
+ * @param string the text to be parsed
+ * @param string the URL to the folder containing the smiley images
+ * @return string
+ */
+if (! function_exists('parse_smileys'))
+{
+ function parse_smileys($str = '', $image_url = '', $smileys = NULL)
+ {
+ if ($image_url == '')
+ {
+ return $str;
+ }
+
+ if ( ! is_array($smileys))
+ {
+ if (FALSE === ($smileys = _get_smiley_array()))
+ {
+ return $str;
+ }
+ }
+
+ // Add a trailing slash to the file path if needed
+ $image_url = preg_replace("/(.+?)\/*$/", "\\1/", $image_url);
+
+ foreach ($smileys as $key => $val)
+ {
+ $str = str_replace($key, "", $str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Get Smiley Array
+ *
+ * Fetches the config/smiley.php file
+ *
+ * @access private
+ * @return mixed
+ */
+if (! function_exists('_get_smiley_array'))
+{
+ function _get_smiley_array()
+ {
+ if ( ! file_exists(APPPATH.'config/smileys'.EXT))
+ {
+ return FALSE;
+ }
+
+ include(APPPATH.'config/smileys'.EXT);
+
+ if ( ! isset($smileys) OR ! is_array($smileys))
+ {
+ return FALSE;
+ }
+
+ return $smileys;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/system/helpers/.svn/text-base/string_helper.php.svn-base b/system/helpers/.svn/text-base/string_helper.php.svn-base
new file mode 100644
index 0000000..f68f44a
--- /dev/null
+++ b/system/helpers/.svn/text-base/string_helper.php.svn-base
@@ -0,0 +1,271 @@
+ $val)
+ {
+ $str[$key] = strip_slashes($val);
+ }
+ }
+ else
+ {
+ $str = stripslashes($str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Strip Quotes
+ *
+ * Removes single and double quotes from a string
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('strip_quotes'))
+{
+ function strip_quotes($str)
+ {
+ return str_replace(array('"', "'"), '', $str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Quotes to Entities
+ *
+ * Converts single and double quotes to entities
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('quotes_to_entities'))
+{
+ function quotes_to_entities($str)
+ {
+ return str_replace(array("\'","\"","'",'"'), array("'",""","'","""), $str);
+ }
+}
+
+// ------------------------------------------------------------------------
+/**
+ * Reduce Double Slashes
+ *
+ * Converts double slashes in a string to a single slash,
+ * except those found in http://
+ *
+ * http://www.some-site.com//index.php
+ *
+ * becomes:
+ *
+ * http://www.some-site.com/index.php
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('reduce_double_slashes'))
+{
+ function reduce_double_slashes($str)
+ {
+ return preg_replace("#([^:])//+#", "\\1/", $str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Reduce Multiples
+ *
+ * Reduces multiple instances of a particular character. Example:
+ *
+ * Fred, Bill,, Joe, Jimmy
+ *
+ * becomes:
+ *
+ * Fred, Bill, Joe, Jimmy
+ *
+ * @access public
+ * @param string
+ * @param string the character you wish to reduce
+ * @param bool TRUE/FALSE - whether to trim the character from the beginning/end
+ * @return string
+ */
+if (! function_exists('reduce_multiples'))
+{
+ function reduce_multiples($str, $character = ',', $trim = FALSE)
+ {
+ $str = preg_replace('#'.preg_quote($character, '#').'{2,}#', $character, $str);
+
+ if ($trim === TRUE)
+ {
+ $str = trim($str, $character);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Create a Random String
+ *
+ * Useful for generating passwords or hashes.
+ *
+ * @access public
+ * @param string type of random string. Options: alunum, numeric, nozero, unique
+ * @param integer number of characters
+ * @return string
+ */
+if (! function_exists('random_string'))
+{
+ function random_string($type = 'alnum', $len = 8)
+ {
+ switch($type)
+ {
+ case 'alnum' :
+ case 'numeric' :
+ case 'nozero' :
+
+ switch ($type)
+ {
+ case 'alnum' : $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ break;
+ case 'numeric' : $pool = '0123456789';
+ break;
+ case 'nozero' : $pool = '123456789';
+ break;
+ }
+
+ $str = '';
+ for ($i=0; $i < $len; $i++)
+ {
+ $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
+ }
+ return $str;
+ break;
+ case 'unique' : return md5(uniqid(mt_rand()));
+ break;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Alternator
+ *
+ * Allows strings to be alternated. See docs...
+ *
+ * @access public
+ * @param string (as many parameters as needed)
+ * @return string
+ */
+if (! function_exists('alternator'))
+{
+ function alternator()
+ {
+ static $i;
+
+ if (func_num_args() == 0)
+ {
+ $i = 0;
+ return '';
+ }
+ $args = func_get_args();
+ return $args[($i++ % count($args))];
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Repeater function
+ *
+ * @access public
+ * @param string
+ * @param integer number of repeats
+ * @return string
+ */
+if (! function_exists('repeater'))
+{
+ function repeater($data, $num = 1)
+ {
+ return (($num > 0) ? str_repeat($data, $num) : '');
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/system/helpers/.svn/text-base/text_helper.php.svn-base b/system/helpers/.svn/text-base/text_helper.php.svn-base
new file mode 100644
index 0000000..21ab778
--- /dev/null
+++ b/system/helpers/.svn/text-base/text_helper.php.svn-base
@@ -0,0 +1,439 @@
+= $n)
+ {
+ return trim($out).$end_char;
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * High ASCII to Entities
+ *
+ * Converts High ascii text and MS Word special characters to character entities
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('ascii_to_entities'))
+{
+ function ascii_to_entities($str)
+ {
+ $count = 1;
+ $out = '';
+ $temp = array();
+
+ for ($i = 0, $s = strlen($str); $i < $s; $i++)
+ {
+ $ordinal = ord($str[$i]);
+
+ if ($ordinal < 128)
+ {
+ $out .= $str[$i];
+ }
+ else
+ {
+ if (count($temp) == 0)
+ {
+ $count = ($ordinal < 224) ? 2 : 3;
+ }
+
+ $temp[] = $ordinal;
+
+ if (count($temp) == $count)
+ {
+ $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
+
+ $out .= ''.$number.';';
+ $count = 1;
+ $temp = array();
+ }
+ }
+ }
+
+ return $out;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Entities to ASCII
+ *
+ * Converts character entities back to ASCII
+ *
+ * @access public
+ * @param string
+ * @param bool
+ * @return string
+ */
+if (! function_exists('entities_to_ascii'))
+{
+ function entities_to_ascii($str, $all = TRUE)
+ {
+ if (preg_match_all('/\(\d+)\;/', $str, $matches))
+ {
+ for ($i = 0, $s = count($matches['0']); $i < $s; $i++)
+ {
+ $digits = $matches['1'][$i];
+
+ $out = '';
+
+ if ($digits < 128)
+ {
+ $out .= chr($digits);
+
+ }
+ elseif ($digits < 2048)
+ {
+ $out .= chr(192 + (($digits - ($digits % 64)) / 64));
+ $out .= chr(128 + ($digits % 64));
+ }
+ else
+ {
+ $out .= chr(224 + (($digits - ($digits % 4096)) / 4096));
+ $out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64));
+ $out .= chr(128 + ($digits % 64));
+ }
+
+ $str = str_replace($matches['0'][$i], $out, $str);
+ }
+ }
+
+ if ($all)
+ {
+ $str = str_replace(array("&", "<", ">", """, "'", "-"),
+ array("&","<",">","\"", "'", "-"),
+ $str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Word Censoring Function
+ *
+ * Supply a string and an array of disallowed words and any
+ * matched words will be converted to #### or to the replacement
+ * word you've submitted.
+ *
+ * @access public
+ * @param string the text string
+ * @param string the array of censoered words
+ * @param string the optional replacement value
+ * @return string
+ */
+if (! function_exists('word_censor'))
+{
+ function word_censor($str, $censored, $replacement = '')
+ {
+ if ( ! is_array($censored))
+ {
+ return $str;
+ }
+
+ $str = ' '.$str.' ';
+ foreach ($censored as $badword)
+ {
+ if ($replacement != '')
+ {
+ $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword)).")\b/i", $replacement, $str);
+ }
+ else
+ {
+ $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword)).")\b/ie", "str_repeat('#', strlen('\\1'))", $str);
+ }
+ }
+
+ return trim($str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Code Highlighter
+ *
+ * Colorizes code strings
+ *
+ * @access public
+ * @param string the text string
+ * @return string
+ */
+if (! function_exists('highlight_code'))
+{
+ function highlight_code($str)
+ {
+ // The highlight string function encodes and highlights
+ // brackets so we need them to start raw
+ $str = str_replace(array('<', '>'), array('<', '>'), $str);
+
+ // Replace any existing PHP tags to temporary markers so they don't accidentally
+ // break the string out of PHP, and thus, thwart the highlighting.
+
+ $str = str_replace(array('', '?>', '<%', '%>', '\\', ''),
+ array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), $str);
+
+ // The highlight_string function requires that the text be surrounded
+ // by PHP tags. Since we don't know if A) the submitted text has PHP tags,
+ // or B) whether the PHP tags enclose the entire string, we will add our
+ // own PHP tags around the string along with some markers to make replacement easier later
+
+ $str = '';
+
+ // All the magic happens here, baby!
+ $str = highlight_string($str, TRUE);
+
+ // Prior to PHP 5, the highlight function used icky font tags
+ // so we'll replace them with span tags.
+ if (abs(phpversion()) < 5)
+ {
+ $str = str_replace(array(''), array(''), $str);
+ $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);
+ }
+
+ // Remove our artificially added PHP
+ $str = preg_replace("#\.+?tempstart\ (?:\)?#is", "\n", $str);
+ $str = preg_replace("#tempend.+#is", "\n", $str);
+
+ // Replace our markers back to PHP tags.
+ $str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
+ array('<?', '?>', '<%', '%>', '\\', '</script>'), $str);
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Phrase Highlighter
+ *
+ * Highlights a phrase within a text string
+ *
+ * @access public
+ * @param string the text string
+ * @param string the phrase you'd like to highlight
+ * @param string the openging tag to precede the phrase with
+ * @param string the closing tag to end the phrase with
+ * @return string
+ */
+if (! function_exists('highlight_phrase'))
+{
+ function highlight_phrase($str, $phrase, $tag_open = '', $tag_close = '')
+ {
+ if ($str == '')
+ {
+ return '';
+ }
+
+ if ($phrase != '')
+ {
+ return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Word Wrap
+ *
+ * Wraps text at the specified character. Maintains the integrity of words.
+ * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor
+ * will URLs.
+ *
+ * @access public
+ * @param string the text string
+ * @param integer the number of characters to wrap at
+ * @return string
+ */
+if (! function_exists('word_wrap'))
+{
+ function word_wrap($str, $charlim = '76')
+ {
+ // Se the character limit
+ if ( ! is_numeric($charlim))
+ $charlim = 76;
+
+ // Reduce multiple spaces
+ $str = preg_replace("| +|", " ", $str);
+
+ // Standardize newlines
+ $str = preg_replace("/\r\n|\r/", "\n", $str);
+
+ // If the current word is surrounded by {unwrap} tags we'll
+ // strip the entire chunk and replace it with a marker.
+ $unwrap = array();
+ if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
+ {
+ for ($i = 0; $i < count($matches['0']); $i++)
+ {
+ $unwrap[] = $matches['1'][$i];
+ $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
+ }
+ }
+
+ // Use PHP's native function to do the initial wordwrap.
+ // We set the cut flag to FALSE so that any individual words that are
+ // too long get left alone. In the next step we'll deal with them.
+ $str = wordwrap($str, $charlim, "\n", FALSE);
+
+ // Split the string into individual lines of text and cycle through them
+ $output = "";
+ foreach (explode("\n", $str) as $line)
+ {
+ // Is the line within the allowed character count?
+ // If so we'll join it to the output and continue
+ if (strlen($line) <= $charlim)
+ {
+ $output .= $line."\n";
+ continue;
+ }
+
+ $temp = '';
+ while((strlen($line)) > $charlim)
+ {
+ // If the over-length word is a URL we won't wrap it
+ if (preg_match("!\[url.+\]|://|wwww.!", $line))
+ {
+ break;
+ }
+
+ // Trim the word down
+ $temp .= substr($line, 0, $charlim-1);
+ $line = substr($line, $charlim-1);
+ }
+
+ // If $temp contains data it means we had to split up an over-length
+ // word into smaller chunks so we'll add it back to our current line
+ if ($temp != '')
+ {
+ $output .= $temp . "\n" . $line;
+ }
+ else
+ {
+ $output .= $line;
+ }
+
+ $output .= "\n";
+ }
+
+ // Put our markers back
+ if (count($unwrap) > 0)
+ {
+ foreach ($unwrap as $key => $val)
+ {
+ $output = str_replace("{{unwrapped".$key."}}", $val, $output);
+ }
+ }
+
+ // Remove the unwrap tags
+ $output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output);
+
+ return $output;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/system/helpers/.svn/text-base/typography_helper.php.svn-base b/system/helpers/.svn/text-base/typography_helper.php.svn-base
new file mode 100644
index 0000000..4d9a1bb
--- /dev/null
+++ b/system/helpers/.svn/text-base/typography_helper.php.svn-base
@@ -0,0 +1,545 @@
+",$str);
+ $ct = count($ex);
+
+ $newstr = "";
+ for ($i = 0; $i < $ct; $i++)
+ {
+ if (($i % 2) == 0)
+ {
+ $newstr .= nl2br($ex[$i]);
+ }
+ else
+ {
+ $newstr .= $ex[$i];
+ }
+
+ if ($ct - 1 != $i)
+ $newstr .= "pre>";
+ }
+
+ return $newstr;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Auto Typography Wrapper Function
+ *
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('auto_typography'))
+{
+ function auto_typography($str)
+ {
+ $TYPE = new Auto_typography();
+ return $TYPE->convert($str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Auto Typography Class
+ *
+ *
+ * @access private
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/
+ */
+class Auto_typography {
+
+ // Block level elements that should not be wrapped inside
tags
+ var $block_elements = 'div|blockquote|pre|code|h\d|script|ol|ul';
+
+ // Elements that should not have
and tags within them.
+ var $skip_elements = 'pre|ol|ul';
+
+ // Tags we want the parser to completely ignore when splitting the string.
+ var $ignore_elements = 'a|b|i|em|strong|span|img|li';
+
+
+ /**
+ * Main Processing Function
+ *
+ */
+ function convert($str)
+ {
+ if ($str == '')
+ {
+ return '';
+ }
+
+ $str = ' '.$str.' ';
+
+ // Standardize Newlines to make matching easier
+ $str = preg_replace("/(\r\n|\r)/", "\n", $str);
+
+ /*
+ * Reduce line breaks
+ *
+ * If there are more than two consecutive line
+ * breaks we'll compress them down to a maximum
+ * of two since there's no benefit to more.
+ *
+ */
+ $str = preg_replace("/\n\n+/", "\n\n", $str);
+
+ /*
+ * Convert quotes within tags to temporary marker
+ *
+ * We don't want quotes converted within
+ * tags so we'll temporarily convert them to
+ * {@DQ} and {@SQ}
+ *
+ */
+ if (preg_match_all("#\<.+?>#si", $str, $matches))
+ {
+ for ($i = 0; $i < count($matches['0']); $i++)
+ {
+ $str = str_replace($matches['0'][$i],
+ str_replace(array("'",'"'), array('{@SQ}', '{@DQ}'), $matches['0'][$i]),
+ $str);
+ }
+ }
+
+
+ /*
+ * Add closing/opening paragraph tags before/after "block" elements
+ *
+ * Since block elements (like ,
, etc.) do not get
+ * wrapped in paragraph tags we will add a closing
tag just before
+ * each block element starts and an opening
tag right after the block element
+ * ends. Later on we'll do some further clean up.
+ *
+ */
+ $str = preg_replace("#(<)(".$this->block_elements.")(.*?>)#", "
", $str);
+
+ /*
+ * Convert "ignore" tags to temporary marker
+ *
+ * The parser splits out the string at every tag
+ * it encounters. Certain inline tags, like image
+ * tags, links, span tags, etc. will be adversely
+ * affected if they are split out so we'll convert
+ * the opening < temporarily to: {@TAG}
+ *
+ */
+ $str = preg_replace("#<(/*)(".$this->ignore_elements.")#i", "{@TAG}\\1\\2", $str);
+
+ /*
+ * Split the string at every tag
+ *
+ * This creates an array with this prototype:
+ *
+ * [array]
+ * {
+ * [0] =
+ * [1] = Content contained between the tags
+ * [2] =
+ * Etc...
+ * }
+ *
+ */
+ $chunks = preg_split('/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
+
+ /*
+ * Build our finalized string
+ *
+ * We'll cycle through the array, skipping tags,
+ * and processing the contained text
+ *
+ */
+ $str = '';
+ $process = TRUE;
+ foreach ($chunks as $chunk)
+ {
+ /*
+ * Are we dealing with a tag?
+ *
+ * If so, we'll skip the processing for this cycle.
+ * Well also set the "process" flag which allows us
+ * to skip
tags and a few other things.
+ *
+ */
+ if (preg_match("#<(/*)(".$this->block_elements.").*?\>#", $chunk, $match))
+ {
+ if (preg_match("#".$this->skip_elements."#", $match['2']))
+ {
+ $process = ($match['1'] == '/') ? TRUE : FALSE;
+ }
+
+ $str .= $chunk;
+ continue;
+ }
+
+ if ($process == FALSE)
+ {
+ $str .= $chunk;
+ continue;
+ }
+
+ // Convert Newlines into
and tags
+ $str .= $this->format_newlines($chunk);
+ }
+
+ // FINAL CLEAN UP
+ // IMPORTANT: DO NOT ALTER THE ORDER OF THE ITEMS BELOW!
+
+ /*
+ * Clean up paragraph tags before/after "block" elements
+ *
+ * Earlier we added
tags before/after block level elements.
+ * Then, we added paragraph tags around double line breaks. This
+ * potentially created incorrectly formatted paragraphs so we'll
+ * clean it up here.
+ *
+ */
+ $str = preg_replace("#
#", "\\1\\2\\3", $str);
+
+ // Convert Quotes and other characters
+ $str = $this->format_characters($str);
+
+ // Fix an artifact that happens during the paragraph replacement
+ $str = preg_replace('#(
\n*
)#', '', $str);
+
+ // If the user submitted their own paragraph tags with class data
+ // in them we will retain them instead of using our tags.
+ $str = preg_replace('#()
#', "\\1", $str);
+
+ // Final clean up
+ $str = str_replace(
+ array(
+ '
+
+
+
+
\ No newline at end of file
diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php
new file mode 100755
index 0000000..bf70a67
--- /dev/null
+++ b/system/helpers/inflector_helper.php
@@ -0,0 +1,167 @@
+
\ No newline at end of file
diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php
new file mode 100755
index 0000000..30d26d6
--- /dev/null
+++ b/system/helpers/path_helper.php
@@ -0,0 +1,70 @@
+
\ No newline at end of file
diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php
new file mode 100755
index 0000000..7552fd8
--- /dev/null
+++ b/system/helpers/security_helper.php
@@ -0,0 +1,124 @@
+input->xss_clean($str, $charset);
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Hash encode a string
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('dohash'))
+{
+ function dohash($str, $type = 'sha1')
+ {
+ if ($type == 'sha1')
+ {
+ if ( ! function_exists('sha1'))
+ {
+ if ( ! function_exists('mhash'))
+ {
+ require_once(BASEPATH.'libraries/Sha1'.EXT);
+ $SH = new CI_SHA;
+ return $SH->generate($str);
+ }
+ else
+ {
+ return bin2hex(mhash(MHASH_SHA1, $str));
+ }
+ }
+ else
+ {
+ return sha1($str);
+ }
+ }
+ else
+ {
+ return md5($str);
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Strip Image Tags
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('strip_image_tags'))
+{
+ function strip_image_tags($str)
+ {
+ $str = preg_replace("##", "\\1", $str);
+ $str = preg_replace("##", "\\1", $str);
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Convert PHP tags to entities
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('encode_php_tags'))
+{
+ function encode_php_tags($str)
+ {
+ return str_replace(array(''), array('<?php', '<?PHP', '<?', '?>'), $str);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php
new file mode 100755
index 0000000..25962eb
--- /dev/null
+++ b/system/helpers/smiley_helper.php
@@ -0,0 +1,173 @@
+
+ function insert_smiley(smiley)
+ {
+ document.{$form_name}.{$form_field}.value += " " + smiley;
+ }
+
+EOF;
+ }
+}
+// ------------------------------------------------------------------------
+
+/**
+ * Get Clickable Smileys
+ *
+ * Returns an array of image tag links that can be clicked to be inserted
+ * into a form field.
+ *
+ * @access public
+ * @param string the URL to the folder containing the smiley images
+ * @return array
+ */
+if (! function_exists('get_clickable_smileys'))
+{
+ function get_clickable_smileys($image_url = '', $smileys = NULL)
+ {
+ if ( ! is_array($smileys))
+ {
+ if (FALSE === ($smileys = _get_smiley_array()))
+ {
+ return $smileys;
+ }
+ }
+
+ // Add a trailing slash to the file path if needed
+ $image_url = preg_replace("/(.+?)\/*$/", "\\1/", $image_url);
+
+ $used = array();
+ foreach ($smileys as $key => $val)
+ {
+ // Keep duplicates from being used, which can happen if the
+ // mapping array contains multiple identical replacements. For example:
+ // :-) and :) might be replaced with the same image so both smileys
+ // will be in the array.
+ if (isset($used[$smileys[$key][0]]))
+ {
+ continue;
+ }
+
+ $link[] = "";
+
+ $used[$smileys[$key][0]] = TRUE;
+ }
+
+ return $link;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Parse Smileys
+ *
+ * Takes a string as input and swaps any contained smileys for the actual image
+ *
+ * @access public
+ * @param string the text to be parsed
+ * @param string the URL to the folder containing the smiley images
+ * @return string
+ */
+if (! function_exists('parse_smileys'))
+{
+ function parse_smileys($str = '', $image_url = '', $smileys = NULL)
+ {
+ if ($image_url == '')
+ {
+ return $str;
+ }
+
+ if ( ! is_array($smileys))
+ {
+ if (FALSE === ($smileys = _get_smiley_array()))
+ {
+ return $str;
+ }
+ }
+
+ // Add a trailing slash to the file path if needed
+ $image_url = preg_replace("/(.+?)\/*$/", "\\1/", $image_url);
+
+ foreach ($smileys as $key => $val)
+ {
+ $str = str_replace($key, "", $str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Get Smiley Array
+ *
+ * Fetches the config/smiley.php file
+ *
+ * @access private
+ * @return mixed
+ */
+if (! function_exists('_get_smiley_array'))
+{
+ function _get_smiley_array()
+ {
+ if ( ! file_exists(APPPATH.'config/smileys'.EXT))
+ {
+ return FALSE;
+ }
+
+ include(APPPATH.'config/smileys'.EXT);
+
+ if ( ! isset($smileys) OR ! is_array($smileys))
+ {
+ return FALSE;
+ }
+
+ return $smileys;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php
new file mode 100755
index 0000000..f68f44a
--- /dev/null
+++ b/system/helpers/string_helper.php
@@ -0,0 +1,271 @@
+ $val)
+ {
+ $str[$key] = strip_slashes($val);
+ }
+ }
+ else
+ {
+ $str = stripslashes($str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Strip Quotes
+ *
+ * Removes single and double quotes from a string
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('strip_quotes'))
+{
+ function strip_quotes($str)
+ {
+ return str_replace(array('"', "'"), '', $str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Quotes to Entities
+ *
+ * Converts single and double quotes to entities
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('quotes_to_entities'))
+{
+ function quotes_to_entities($str)
+ {
+ return str_replace(array("\'","\"","'",'"'), array("'",""","'","""), $str);
+ }
+}
+
+// ------------------------------------------------------------------------
+/**
+ * Reduce Double Slashes
+ *
+ * Converts double slashes in a string to a single slash,
+ * except those found in http://
+ *
+ * http://www.some-site.com//index.php
+ *
+ * becomes:
+ *
+ * http://www.some-site.com/index.php
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('reduce_double_slashes'))
+{
+ function reduce_double_slashes($str)
+ {
+ return preg_replace("#([^:])//+#", "\\1/", $str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Reduce Multiples
+ *
+ * Reduces multiple instances of a particular character. Example:
+ *
+ * Fred, Bill,, Joe, Jimmy
+ *
+ * becomes:
+ *
+ * Fred, Bill, Joe, Jimmy
+ *
+ * @access public
+ * @param string
+ * @param string the character you wish to reduce
+ * @param bool TRUE/FALSE - whether to trim the character from the beginning/end
+ * @return string
+ */
+if (! function_exists('reduce_multiples'))
+{
+ function reduce_multiples($str, $character = ',', $trim = FALSE)
+ {
+ $str = preg_replace('#'.preg_quote($character, '#').'{2,}#', $character, $str);
+
+ if ($trim === TRUE)
+ {
+ $str = trim($str, $character);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Create a Random String
+ *
+ * Useful for generating passwords or hashes.
+ *
+ * @access public
+ * @param string type of random string. Options: alunum, numeric, nozero, unique
+ * @param integer number of characters
+ * @return string
+ */
+if (! function_exists('random_string'))
+{
+ function random_string($type = 'alnum', $len = 8)
+ {
+ switch($type)
+ {
+ case 'alnum' :
+ case 'numeric' :
+ case 'nozero' :
+
+ switch ($type)
+ {
+ case 'alnum' : $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ break;
+ case 'numeric' : $pool = '0123456789';
+ break;
+ case 'nozero' : $pool = '123456789';
+ break;
+ }
+
+ $str = '';
+ for ($i=0; $i < $len; $i++)
+ {
+ $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
+ }
+ return $str;
+ break;
+ case 'unique' : return md5(uniqid(mt_rand()));
+ break;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Alternator
+ *
+ * Allows strings to be alternated. See docs...
+ *
+ * @access public
+ * @param string (as many parameters as needed)
+ * @return string
+ */
+if (! function_exists('alternator'))
+{
+ function alternator()
+ {
+ static $i;
+
+ if (func_num_args() == 0)
+ {
+ $i = 0;
+ return '';
+ }
+ $args = func_get_args();
+ return $args[($i++ % count($args))];
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Repeater function
+ *
+ * @access public
+ * @param string
+ * @param integer number of repeats
+ * @return string
+ */
+if (! function_exists('repeater'))
+{
+ function repeater($data, $num = 1)
+ {
+ return (($num > 0) ? str_repeat($data, $num) : '');
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php
new file mode 100755
index 0000000..21ab778
--- /dev/null
+++ b/system/helpers/text_helper.php
@@ -0,0 +1,439 @@
+= $n)
+ {
+ return trim($out).$end_char;
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * High ASCII to Entities
+ *
+ * Converts High ascii text and MS Word special characters to character entities
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('ascii_to_entities'))
+{
+ function ascii_to_entities($str)
+ {
+ $count = 1;
+ $out = '';
+ $temp = array();
+
+ for ($i = 0, $s = strlen($str); $i < $s; $i++)
+ {
+ $ordinal = ord($str[$i]);
+
+ if ($ordinal < 128)
+ {
+ $out .= $str[$i];
+ }
+ else
+ {
+ if (count($temp) == 0)
+ {
+ $count = ($ordinal < 224) ? 2 : 3;
+ }
+
+ $temp[] = $ordinal;
+
+ if (count($temp) == $count)
+ {
+ $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
+
+ $out .= ''.$number.';';
+ $count = 1;
+ $temp = array();
+ }
+ }
+ }
+
+ return $out;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Entities to ASCII
+ *
+ * Converts character entities back to ASCII
+ *
+ * @access public
+ * @param string
+ * @param bool
+ * @return string
+ */
+if (! function_exists('entities_to_ascii'))
+{
+ function entities_to_ascii($str, $all = TRUE)
+ {
+ if (preg_match_all('/\(\d+)\;/', $str, $matches))
+ {
+ for ($i = 0, $s = count($matches['0']); $i < $s; $i++)
+ {
+ $digits = $matches['1'][$i];
+
+ $out = '';
+
+ if ($digits < 128)
+ {
+ $out .= chr($digits);
+
+ }
+ elseif ($digits < 2048)
+ {
+ $out .= chr(192 + (($digits - ($digits % 64)) / 64));
+ $out .= chr(128 + ($digits % 64));
+ }
+ else
+ {
+ $out .= chr(224 + (($digits - ($digits % 4096)) / 4096));
+ $out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64));
+ $out .= chr(128 + ($digits % 64));
+ }
+
+ $str = str_replace($matches['0'][$i], $out, $str);
+ }
+ }
+
+ if ($all)
+ {
+ $str = str_replace(array("&", "<", ">", """, "'", "-"),
+ array("&","<",">","\"", "'", "-"),
+ $str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Word Censoring Function
+ *
+ * Supply a string and an array of disallowed words and any
+ * matched words will be converted to #### or to the replacement
+ * word you've submitted.
+ *
+ * @access public
+ * @param string the text string
+ * @param string the array of censoered words
+ * @param string the optional replacement value
+ * @return string
+ */
+if (! function_exists('word_censor'))
+{
+ function word_censor($str, $censored, $replacement = '')
+ {
+ if ( ! is_array($censored))
+ {
+ return $str;
+ }
+
+ $str = ' '.$str.' ';
+ foreach ($censored as $badword)
+ {
+ if ($replacement != '')
+ {
+ $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword)).")\b/i", $replacement, $str);
+ }
+ else
+ {
+ $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword)).")\b/ie", "str_repeat('#', strlen('\\1'))", $str);
+ }
+ }
+
+ return trim($str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Code Highlighter
+ *
+ * Colorizes code strings
+ *
+ * @access public
+ * @param string the text string
+ * @return string
+ */
+if (! function_exists('highlight_code'))
+{
+ function highlight_code($str)
+ {
+ // The highlight string function encodes and highlights
+ // brackets so we need them to start raw
+ $str = str_replace(array('<', '>'), array('<', '>'), $str);
+
+ // Replace any existing PHP tags to temporary markers so they don't accidentally
+ // break the string out of PHP, and thus, thwart the highlighting.
+
+ $str = str_replace(array('', '?>', '<%', '%>', '\\', ''),
+ array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), $str);
+
+ // The highlight_string function requires that the text be surrounded
+ // by PHP tags. Since we don't know if A) the submitted text has PHP tags,
+ // or B) whether the PHP tags enclose the entire string, we will add our
+ // own PHP tags around the string along with some markers to make replacement easier later
+
+ $str = '';
+
+ // All the magic happens here, baby!
+ $str = highlight_string($str, TRUE);
+
+ // Prior to PHP 5, the highlight function used icky font tags
+ // so we'll replace them with span tags.
+ if (abs(phpversion()) < 5)
+ {
+ $str = str_replace(array(''), array(''), $str);
+ $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);
+ }
+
+ // Remove our artificially added PHP
+ $str = preg_replace("#\.+?tempstart\ (?:\)?#is", "\n", $str);
+ $str = preg_replace("#tempend.+#is", "\n", $str);
+
+ // Replace our markers back to PHP tags.
+ $str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
+ array('<?', '?>', '<%', '%>', '\\', '</script>'), $str);
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Phrase Highlighter
+ *
+ * Highlights a phrase within a text string
+ *
+ * @access public
+ * @param string the text string
+ * @param string the phrase you'd like to highlight
+ * @param string the openging tag to precede the phrase with
+ * @param string the closing tag to end the phrase with
+ * @return string
+ */
+if (! function_exists('highlight_phrase'))
+{
+ function highlight_phrase($str, $phrase, $tag_open = '', $tag_close = '')
+ {
+ if ($str == '')
+ {
+ return '';
+ }
+
+ if ($phrase != '')
+ {
+ return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Word Wrap
+ *
+ * Wraps text at the specified character. Maintains the integrity of words.
+ * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor
+ * will URLs.
+ *
+ * @access public
+ * @param string the text string
+ * @param integer the number of characters to wrap at
+ * @return string
+ */
+if (! function_exists('word_wrap'))
+{
+ function word_wrap($str, $charlim = '76')
+ {
+ // Se the character limit
+ if ( ! is_numeric($charlim))
+ $charlim = 76;
+
+ // Reduce multiple spaces
+ $str = preg_replace("| +|", " ", $str);
+
+ // Standardize newlines
+ $str = preg_replace("/\r\n|\r/", "\n", $str);
+
+ // If the current word is surrounded by {unwrap} tags we'll
+ // strip the entire chunk and replace it with a marker.
+ $unwrap = array();
+ if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
+ {
+ for ($i = 0; $i < count($matches['0']); $i++)
+ {
+ $unwrap[] = $matches['1'][$i];
+ $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
+ }
+ }
+
+ // Use PHP's native function to do the initial wordwrap.
+ // We set the cut flag to FALSE so that any individual words that are
+ // too long get left alone. In the next step we'll deal with them.
+ $str = wordwrap($str, $charlim, "\n", FALSE);
+
+ // Split the string into individual lines of text and cycle through them
+ $output = "";
+ foreach (explode("\n", $str) as $line)
+ {
+ // Is the line within the allowed character count?
+ // If so we'll join it to the output and continue
+ if (strlen($line) <= $charlim)
+ {
+ $output .= $line."\n";
+ continue;
+ }
+
+ $temp = '';
+ while((strlen($line)) > $charlim)
+ {
+ // If the over-length word is a URL we won't wrap it
+ if (preg_match("!\[url.+\]|://|wwww.!", $line))
+ {
+ break;
+ }
+
+ // Trim the word down
+ $temp .= substr($line, 0, $charlim-1);
+ $line = substr($line, $charlim-1);
+ }
+
+ // If $temp contains data it means we had to split up an over-length
+ // word into smaller chunks so we'll add it back to our current line
+ if ($temp != '')
+ {
+ $output .= $temp . "\n" . $line;
+ }
+ else
+ {
+ $output .= $line;
+ }
+
+ $output .= "\n";
+ }
+
+ // Put our markers back
+ if (count($unwrap) > 0)
+ {
+ foreach ($unwrap as $key => $val)
+ {
+ $output = str_replace("{{unwrapped".$key."}}", $val, $output);
+ }
+ }
+
+ // Remove the unwrap tags
+ $output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output);
+
+ return $output;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php
new file mode 100755
index 0000000..4d9a1bb
--- /dev/null
+++ b/system/helpers/typography_helper.php
@@ -0,0 +1,545 @@
+",$str);
+ $ct = count($ex);
+
+ $newstr = "";
+ for ($i = 0; $i < $ct; $i++)
+ {
+ if (($i % 2) == 0)
+ {
+ $newstr .= nl2br($ex[$i]);
+ }
+ else
+ {
+ $newstr .= $ex[$i];
+ }
+
+ if ($ct - 1 != $i)
+ $newstr .= "pre>";
+ }
+
+ return $newstr;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Auto Typography Wrapper Function
+ *
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if (! function_exists('auto_typography'))
+{
+ function auto_typography($str)
+ {
+ $TYPE = new Auto_typography();
+ return $TYPE->convert($str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Auto Typography Class
+ *
+ *
+ * @access private
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/
+ */
+class Auto_typography {
+
+ // Block level elements that should not be wrapped inside
tags
+ var $block_elements = 'div|blockquote|pre|code|h\d|script|ol|ul';
+
+ // Elements that should not have
and tags within them.
+ var $skip_elements = 'pre|ol|ul';
+
+ // Tags we want the parser to completely ignore when splitting the string.
+ var $ignore_elements = 'a|b|i|em|strong|span|img|li';
+
+
+ /**
+ * Main Processing Function
+ *
+ */
+ function convert($str)
+ {
+ if ($str == '')
+ {
+ return '';
+ }
+
+ $str = ' '.$str.' ';
+
+ // Standardize Newlines to make matching easier
+ $str = preg_replace("/(\r\n|\r)/", "\n", $str);
+
+ /*
+ * Reduce line breaks
+ *
+ * If there are more than two consecutive line
+ * breaks we'll compress them down to a maximum
+ * of two since there's no benefit to more.
+ *
+ */
+ $str = preg_replace("/\n\n+/", "\n\n", $str);
+
+ /*
+ * Convert quotes within tags to temporary marker
+ *
+ * We don't want quotes converted within
+ * tags so we'll temporarily convert them to
+ * {@DQ} and {@SQ}
+ *
+ */
+ if (preg_match_all("#\<.+?>#si", $str, $matches))
+ {
+ for ($i = 0; $i < count($matches['0']); $i++)
+ {
+ $str = str_replace($matches['0'][$i],
+ str_replace(array("'",'"'), array('{@SQ}', '{@DQ}'), $matches['0'][$i]),
+ $str);
+ }
+ }
+
+
+ /*
+ * Add closing/opening paragraph tags before/after "block" elements
+ *
+ * Since block elements (like ,
, etc.) do not get
+ * wrapped in paragraph tags we will add a closing
tag just before
+ * each block element starts and an opening
tag right after the block element
+ * ends. Later on we'll do some further clean up.
+ *
+ */
+ $str = preg_replace("#(<)(".$this->block_elements.")(.*?>)#", "
", $str);
+
+ /*
+ * Convert "ignore" tags to temporary marker
+ *
+ * The parser splits out the string at every tag
+ * it encounters. Certain inline tags, like image
+ * tags, links, span tags, etc. will be adversely
+ * affected if they are split out so we'll convert
+ * the opening < temporarily to: {@TAG}
+ *
+ */
+ $str = preg_replace("#<(/*)(".$this->ignore_elements.")#i", "{@TAG}\\1\\2", $str);
+
+ /*
+ * Split the string at every tag
+ *
+ * This creates an array with this prototype:
+ *
+ * [array]
+ * {
+ * [0] =
+ * [1] = Content contained between the tags
+ * [2] =
+ * Etc...
+ * }
+ *
+ */
+ $chunks = preg_split('/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
+
+ /*
+ * Build our finalized string
+ *
+ * We'll cycle through the array, skipping tags,
+ * and processing the contained text
+ *
+ */
+ $str = '';
+ $process = TRUE;
+ foreach ($chunks as $chunk)
+ {
+ /*
+ * Are we dealing with a tag?
+ *
+ * If so, we'll skip the processing for this cycle.
+ * Well also set the "process" flag which allows us
+ * to skip
tags and a few other things.
+ *
+ */
+ if (preg_match("#<(/*)(".$this->block_elements.").*?\>#", $chunk, $match))
+ {
+ if (preg_match("#".$this->skip_elements."#", $match['2']))
+ {
+ $process = ($match['1'] == '/') ? TRUE : FALSE;
+ }
+
+ $str .= $chunk;
+ continue;
+ }
+
+ if ($process == FALSE)
+ {
+ $str .= $chunk;
+ continue;
+ }
+
+ // Convert Newlines into
and tags
+ $str .= $this->format_newlines($chunk);
+ }
+
+ // FINAL CLEAN UP
+ // IMPORTANT: DO NOT ALTER THE ORDER OF THE ITEMS BELOW!
+
+ /*
+ * Clean up paragraph tags before/after "block" elements
+ *
+ * Earlier we added
tags before/after block level elements.
+ * Then, we added paragraph tags around double line breaks. This
+ * potentially created incorrectly formatted paragraphs so we'll
+ * clean it up here.
+ *
+ */
+ $str = preg_replace("#
#", "\\1\\2\\3", $str);
+
+ // Convert Quotes and other characters
+ $str = $this->format_characters($str);
+
+ // Fix an artifact that happens during the paragraph replacement
+ $str = preg_replace('#(
\n*
)#', '', $str);
+
+ // If the user submitted their own paragraph tags with class data
+ // in them we will retain them instead of using our tags.
+ $str = preg_replace('#()
#', "\\1", $str);
+
+ // Final clean up
+ $str = str_replace(
+ array(
+ '
+
+
+
+
\ No newline at end of file
diff --git a/system/language/english/.svn/text-base/profiler_lang.php.svn-base b/system/language/english/.svn/text-base/profiler_lang.php.svn-base
new file mode 100644
index 0000000..219a838
--- /dev/null
+++ b/system/language/english/.svn/text-base/profiler_lang.php.svn-base
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/system/language/english/.svn/text-base/scaffolding_lang.php.svn-base b/system/language/english/.svn/text-base/scaffolding_lang.php.svn-base
new file mode 100644
index 0000000..96fe167
--- /dev/null
+++ b/system/language/english/.svn/text-base/scaffolding_lang.php.svn-base
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/system/language/english/.svn/text-base/unit_test_lang.php.svn-base b/system/language/english/.svn/text-base/unit_test_lang.php.svn-base
new file mode 100644
index 0000000..a33cad5
--- /dev/null
+++ b/system/language/english/.svn/text-base/unit_test_lang.php.svn-base
@@ -0,0 +1,22 @@
+
\ No newline at end of file
diff --git a/system/language/english/.svn/text-base/upload_lang.php.svn-base b/system/language/english/.svn/text-base/upload_lang.php.svn-base
new file mode 100644
index 0000000..fa6d7c9
--- /dev/null
+++ b/system/language/english/.svn/text-base/upload_lang.php.svn-base
@@ -0,0 +1,20 @@
+
\ No newline at end of file
diff --git a/system/language/english/.svn/text-base/validation_lang.php.svn-base b/system/language/english/.svn/text-base/validation_lang.php.svn-base
new file mode 100644
index 0000000..1e9ec2c
--- /dev/null
+++ b/system/language/english/.svn/text-base/validation_lang.php.svn-base
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/system/language/english/calendar_lang.php b/system/language/english/calendar_lang.php
new file mode 100755
index 0000000..9ee4a5e
--- /dev/null
+++ b/system/language/english/calendar_lang.php
@@ -0,0 +1,49 @@
+
\ No newline at end of file
diff --git a/system/language/english/date_lang.php b/system/language/english/date_lang.php
new file mode 100755
index 0000000..6b18aa7
--- /dev/null
+++ b/system/language/english/date_lang.php
@@ -0,0 +1,49 @@
+
\ No newline at end of file
diff --git a/system/language/english/db_lang.php b/system/language/english/db_lang.php
new file mode 100755
index 0000000..1e79a70
--- /dev/null
+++ b/system/language/english/db_lang.php
@@ -0,0 +1,25 @@
+
\ No newline at end of file
diff --git a/system/language/english/email_lang.php b/system/language/english/email_lang.php
new file mode 100755
index 0000000..f026865
--- /dev/null
+++ b/system/language/english/email_lang.php
@@ -0,0 +1,21 @@
+
\ No newline at end of file
diff --git a/system/language/english/ftp_lang.php b/system/language/english/ftp_lang.php
new file mode 100755
index 0000000..da744fe
--- /dev/null
+++ b/system/language/english/ftp_lang.php
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php
new file mode 100755
index 0000000..520f17f
--- /dev/null
+++ b/system/language/english/imglib_lang.php
@@ -0,0 +1,21 @@
+
\ No newline at end of file
diff --git a/system/language/english/index.html b/system/language/english/index.html
new file mode 100755
index 0000000..5a1f5d6
--- /dev/null
+++ b/system/language/english/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+403 Forbidden
+
+
+
+
+
+
Directory access is forbidden.
+
+
+
+
\ No newline at end of file
diff --git a/system/language/english/profiler_lang.php b/system/language/english/profiler_lang.php
new file mode 100755
index 0000000..219a838
--- /dev/null
+++ b/system/language/english/profiler_lang.php
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/system/language/english/scaffolding_lang.php b/system/language/english/scaffolding_lang.php
new file mode 100755
index 0000000..96fe167
--- /dev/null
+++ b/system/language/english/scaffolding_lang.php
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/system/language/english/unit_test_lang.php b/system/language/english/unit_test_lang.php
new file mode 100755
index 0000000..a33cad5
--- /dev/null
+++ b/system/language/english/unit_test_lang.php
@@ -0,0 +1,22 @@
+
\ No newline at end of file
diff --git a/system/language/english/upload_lang.php b/system/language/english/upload_lang.php
new file mode 100755
index 0000000..fa6d7c9
--- /dev/null
+++ b/system/language/english/upload_lang.php
@@ -0,0 +1,20 @@
+
\ No newline at end of file
diff --git a/system/language/english/validation_lang.php b/system/language/english/validation_lang.php
new file mode 100755
index 0000000..1e9ec2c
--- /dev/null
+++ b/system/language/english/validation_lang.php
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/system/language/index.html b/system/language/index.html
new file mode 100755
index 0000000..5a1f5d6
--- /dev/null
+++ b/system/language/index.html
@@ -0,0 +1,15 @@
+
+
+