Title: MagpieRSS
Published: April 25, 2014
Last modified: May 20, 2026

---

# class MagpieRSS {}

## In this article

 * [Methods](https://developer.wordpress.org/reference/classes/magpierss/?output_format=md#methods)
 * [Source](https://developer.wordpress.org/reference/classes/magpierss/?output_format=md#source)
 * [User Contributed Notes](https://developer.wordpress.org/reference/classes/magpierss/?output_format=md#user-contributed-notes)

[ Back to top](https://developer.wordpress.org/reference/classes/magpierss/?output_format=md#wp--skip-link--target)

## 󠀁[Methods](https://developer.wordpress.org/reference/classes/magpierss/?output_format=md#methods)󠁿

| Name | Description | 
| [MagpieRSS::__construct](https://developer.wordpress.org/reference/classes/magpierss/__construct/) | PHP5 constructor. | 
| [MagpieRSS::append](https://developer.wordpress.org/reference/classes/magpierss/append/) | – | 
| [MagpieRSS::append_content](https://developer.wordpress.org/reference/classes/magpierss/append_content/) | – | 
| [MagpieRSS::concat](https://developer.wordpress.org/reference/classes/magpierss/concat/) | – | 
| [MagpieRSS::error](https://developer.wordpress.org/reference/classes/magpierss/error/) | – | 
| [MagpieRSS::feed_cdata](https://developer.wordpress.org/reference/classes/magpierss/feed_cdata/) | – | 
| [MagpieRSS::feed_end_element](https://developer.wordpress.org/reference/classes/magpierss/feed_end_element/) | – | 
| [MagpieRSS::feed_start_element](https://developer.wordpress.org/reference/classes/magpierss/feed_start_element/) | – | 
| [MagpieRSS::is_atom](https://developer.wordpress.org/reference/classes/magpierss/is_atom/) | – | 
| [MagpieRSS::is_rss](https://developer.wordpress.org/reference/classes/magpierss/is_rss/) | – | 
| [MagpieRSS::MagpieRSS](https://developer.wordpress.org/reference/classes/magpierss/magpierss/) | PHP4 constructor. | 
| [MagpieRSS::map_attrs](https://developer.wordpress.org/reference/classes/magpierss/map_attrs/) | – | 
| [MagpieRSS::normalize](https://developer.wordpress.org/reference/classes/magpierss/normalize/) | – |

## 󠀁[Source](https://developer.wordpress.org/reference/classes/magpierss/?output_format=md#source)󠁿

    ```php
    class MagpieRSS {
    	var $parser;
    	var $current_item	= array();	// item currently being parsed
    	var $items			= array();	// collection of parsed items
    	var $channel		= array();	// hash of channel fields
    	var $textinput		= array();
    	var $image			= array();
    	var $feed_type;
    	var $feed_version;

    	// parser variables
    	var $stack				= array(); // parser stack
    	var $inchannel			= false;
    	var $initem 			= false;
    	var $incontent			= false; // if in Atom <content mode="xml"> field
    	var $intextinput		= false;
    	var $inimage 			= false;
    	var $current_field		= '';
    	var $current_namespace	= false;

    	//var $ERROR = "";

    	var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright');

    	/**
    	 * PHP5 constructor.
    	 */
    	function __construct( $source ) {

    		# Check if PHP xml isn't compiled
    		#
    		if ( ! function_exists('xml_parser_create') ) {
    			wp_trigger_error( '', "PHP's XML extension is not available. Please contact your hosting provider to enable PHP's XML extension." );
    			return;
    		}

    		$parser = xml_parser_create();

    		$this->parser = $parser;

    		# pass in parser, and a reference to this object
    		# set up handlers
    		#
    		xml_set_element_handler($this->parser,
    				array( $this, 'feed_start_element' ), array( $this, 'feed_end_element' ) );

    		xml_set_character_data_handler( $this->parser, array( $this, 'feed_cdata' ) );

    		$status = xml_parse( $this->parser, $source );

    		if (! $status ) {
    			$errorcode = xml_get_error_code( $this->parser );
    			if ( $errorcode != XML_ERROR_NONE ) {
    				$xml_error = xml_error_string( $errorcode );
    				$error_line = xml_get_current_line_number($this->parser);
    				$error_col = xml_get_current_column_number($this->parser);
    				$errormsg = "$xml_error at line $error_line, column $error_col";

    				$this->error( $errormsg );
    			}
    		}

    		if ( PHP_VERSION_ID < 80000 ) { // xml_parser_free() has no effect as of PHP 8.0.
    			xml_parser_free( $this->parser );
    		}

    		unset( $this->parser );

    		$this->normalize();
    	}

    	/**
    	 * PHP4 constructor.
    	 */
    	public function MagpieRSS( $source ) {
    		self::__construct( $source );
    	}

    	function feed_start_element($p, $element, &$attrs) {
    		$el = $element = strtolower($element);
    		$attrs = array_change_key_case($attrs, CASE_LOWER);

    		// check for a namespace, and split if found
    		$ns	= false;
    		if ( strpos( $element, ':' ) ) {
    			list($ns, $el) = explode( ':', $element, 2);
    		}
    		if ( $ns and $ns != 'rdf' ) {
    			$this->current_namespace = $ns;
    		}

    		# if feed type isn't set, then this is first element of feed
    		# identify feed from root element
    		#
    		if (!isset($this->feed_type) ) {
    			if ( $el == 'rdf' ) {
    				$this->feed_type = RSS;
    				$this->feed_version = '1.0';
    			}
    			elseif ( $el == 'rss' ) {
    				$this->feed_type = RSS;
    				$this->feed_version = $attrs['version'];
    			}
    			elseif ( $el == 'feed' ) {
    				$this->feed_type = ATOM;
    				$this->feed_version = $attrs['version'];
    				$this->inchannel = true;
    			}
    			return;
    		}

    		if ( $el == 'channel' )
    		{
    			$this->inchannel = true;
    		}
    		elseif ($el == 'item' or $el == 'entry' )
    		{
    			$this->initem = true;
    			if ( isset($attrs['rdf:about']) ) {
    				$this->current_item['about'] = $attrs['rdf:about'];
    			}
    		}

    		// if we're in the default namespace of an RSS feed,
    		//  record textinput or image fields
    		elseif (
    			$this->feed_type == RSS and
    			$this->current_namespace == '' and
    			$el == 'textinput' )
    		{
    			$this->intextinput = true;
    		}

    		elseif (
    			$this->feed_type == RSS and
    			$this->current_namespace == '' and
    			$el == 'image' )
    		{
    			$this->inimage = true;
    		}

    		# handle atom content constructs
    		elseif ( $this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
    		{
    			// avoid clashing w/ RSS mod_content
    			if ($el == 'content' ) {
    				$el = 'atom_content';
    			}

    			$this->incontent = $el;

    		}

    		// if inside an Atom content construct (e.g. content or summary) field treat tags as text
    		elseif ($this->feed_type == ATOM and $this->incontent )
    		{
    			// if tags are inlined, then flatten
    			$attrs_str = join(' ',
    					array_map(array('MagpieRSS', 'map_attrs'),
    					array_keys($attrs),
    					array_values($attrs) ) );

    			$this->append_content( "<$element $attrs_str>"  );

    			array_unshift( $this->stack, $el );
    		}

    		// Atom support many links per containing element.
    		// Magpie treats link elements of type rel='alternate'
    		// as being equivalent to RSS's simple link element.
    		//
    		elseif ($this->feed_type == ATOM and $el == 'link' )
    		{
    			if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' )
    			{
    				$link_el = 'link';
    			}
    			else {
    				$link_el = 'link_' . $attrs['rel'];
    			}

    			$this->append($link_el, $attrs['href']);
    		}
    		// set stack[0] to current element
    		else {
    			array_unshift($this->stack, $el);
    		}
    	}

    	function feed_cdata ($p, $text) {

    		if ($this->feed_type == ATOM and $this->incontent)
    		{
    			$this->append_content( $text );
    		}
    		else {
    			$current_el = join('_', array_reverse($this->stack));
    			$this->append($current_el, $text);
    		}
    	}

    	function feed_end_element ($p, $el) {
    		$el = strtolower($el);

    		if ( $el == 'item' or $el == 'entry' )
    		{
    			$this->items[] = $this->current_item;
    			$this->current_item = array();
    			$this->initem = false;
    		}
    		elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' )
    		{
    			$this->intextinput = false;
    		}
    		elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' )
    		{
    			$this->inimage = false;
    		}
    		elseif ($this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
    		{
    			$this->incontent = false;
    		}
    		elseif ($el == 'channel' or $el == 'feed' )
    		{
    			$this->inchannel = false;
    		}
    		elseif ($this->feed_type == ATOM and $this->incontent  ) {
    			// balance tags properly
    			// note: This may not actually be necessary
    			if ( $this->stack[0] == $el )
    			{
    				$this->append_content("</$el>");
    			}
    			else {
    				$this->append_content("<$el />");
    			}

    			array_shift( $this->stack );
    		}
    		else {
    			array_shift( $this->stack );
    		}

    		$this->current_namespace = false;
    	}

    	function concat (&$str1, $str2="") {
    		if (!isset($str1) ) {
    			$str1="";
    		}
    		$str1 .= $str2;
    	}

    	function append_content($text) {
    		if ( $this->initem ) {
    			$this->concat( $this->current_item[ $this->incontent ], $text );
    		}
    		elseif ( $this->inchannel ) {
    			$this->concat( $this->channel[ $this->incontent ], $text );
    		}
    	}

    	// smart append - field and namespace aware
    	function append($el, $text) {
    		if (!$el) {
    			return;
    		}
    		if ( $this->current_namespace )
    		{
    			if ( $this->initem ) {
    				$this->concat(
    					$this->current_item[ $this->current_namespace ][ $el ], $text);
    			}
    			elseif ($this->inchannel) {
    				$this->concat(
    					$this->channel[ $this->current_namespace][ $el ], $text );
    			}
    			elseif ($this->intextinput) {
    				$this->concat(
    					$this->textinput[ $this->current_namespace][ $el ], $text );
    			}
    			elseif ($this->inimage) {
    				$this->concat(
    					$this->image[ $this->current_namespace ][ $el ], $text );
    			}
    		}
    		else {
    			if ( $this->initem ) {
    				$this->concat(
    					$this->current_item[ $el ], $text);
    			}
    			elseif ($this->intextinput) {
    				$this->concat(
    					$this->textinput[ $el ], $text );
    			}
    			elseif ($this->inimage) {
    				$this->concat(
    					$this->image[ $el ], $text );
    			}
    			elseif ($this->inchannel) {
    				$this->concat(
    					$this->channel[ $el ], $text );
    			}

    		}
    	}

    	function normalize () {
    		// if atom populate rss fields
    		if ( $this->is_atom() ) {
    			$this->channel['description'] = $this->channel['tagline'];
    			for ( $i = 0; $i < count($this->items); $i++) {
    				$item = $this->items[$i];
    				if ( isset($item['summary']) )
    					$item['description'] = $item['summary'];
    				if ( isset($item['atom_content']))
    					$item['content']['encoded'] = $item['atom_content'];

    				$this->items[$i] = $item;
    			}
    		}
    		elseif ( $this->is_rss() ) {
    			$this->channel['tagline'] = $this->channel['description'];
    			for ( $i = 0; $i < count($this->items); $i++) {
    				$item = $this->items[$i];
    				if ( isset($item['description']))
    					$item['summary'] = $item['description'];
    				if ( isset($item['content']['encoded'] ) )
    					$item['atom_content'] = $item['content']['encoded'];

    				$this->items[$i] = $item;
    			}
    		}
    	}

    	function is_rss () {
    		if ( $this->feed_type == RSS ) {
    			return $this->feed_version;
    		}
    		else {
    			return false;
    		}
    	}

    	function is_atom() {
    		if ( $this->feed_type == ATOM ) {
    			return $this->feed_version;
    		}
    		else {
    			return false;
    		}
    	}

    	function map_attrs($k, $v) {
    		return "$k=\"$v\"";
    	}

    	function error( $errormsg, $lvl = E_USER_WARNING ) {
    		if ( MAGPIE_DEBUG ) {
    			wp_trigger_error('', $errormsg, $lvl);
    		} else {
    			error_log( $errormsg, 0);
    		}
    	}

    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/rss.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.0/src/wp-includes/rss.php#L34)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.0/src/wp-includes/rss.php#L34-L399)

## 󠀁[User Contributed Notes](https://developer.wordpress.org/reference/classes/magpierss/?output_format=md#user-contributed-notes)󠁿

 1.  [Skip to note 2 content](https://developer.wordpress.org/reference/classes/magpierss/?output_format=md#comment-content-6250)
 2.   [Felipe Lavín](https://profiles.wordpress.org/felipelavinz/)  [  4 years ago  ](https://developer.wordpress.org/reference/classes/magpierss/#comment-6250)
 3. [You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fmagpierss%2F%23comment-6250)
    Vote results for this note: 0[You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fmagpierss%2F%23comment-6250)
 4. The entire `wp-includes/rss.php` is deprecated, WordPress uses SimplePie since 
    v3.0
 5. If you need to fetch and parse a RSS feed, check out [fetch_feed()](https://developer.wordpress.org/reference/functions/fetch_feed/)
    instead, which will do all the heavy lifting for quickly using SimplePie :-)
 6.  [Log in to add feedback](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fmagpierss%2F%3Freplytocom%3D6250%23feedback-editor-6250)

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fmagpierss%2F)
before being able to contribute a note or feedback.