<?php

/*
Plugin Name: Media feed
Description: Media RSS in RSS2, atom enclosure
Plugin URI: http://samm.dreamhosters.com/wordpress/plugins/
Author: Sam
Version: 0.1
*/

/**
 * Wordpress adds a hyperlink to the_content when the feed item (entry) is an attachment. Set false to stop 
 */

define( 'MyPlugin_PREPEND_ATTACHMENT_IN_FEEDS', false );

$MyPlugin = new MyPlugin();
$MyPlugin->plug_in();

/**
* New class
*/
class MyPlugin
{
	var $options = array(
		'types' => array( 'audio', 'video' )
		);
	var	$media_rss_mediums = array( 'image', 'audio', 'video', 'document', 'executable' );
	var $xml_factory = null;	
	var $did_atom_enclosures = null;
	var $did_rss_enclosures = null;
	var $actions = array(
		'atom_enclosure' => 'atom_enclosure',
		'atom_entry' => 'do_atom_entry',
		'do_feed_atom' => 'do_feed',
		'do_feed_rss2' => 'do_feed',
		'rss2_item' => 'do_rss_item',
		'rss2_ns' => 'rss2_ns',
		'rss_enclosure' => 'rss_enclosure',
		);
	
	function __construct( $options = null )
	{
		# code...
	}
	function MyPlugin( $options = null ) {
		$this->__construct();
	}
	function plug_in() {
		foreach ( $this->actions as $hook => $method ) {
			add_action( $hook, array( &$this, $method ), ( 'do_feed' == $method ? 1 : 10 ) );
		}
	}

	function get_the_attachments() {
		// ?? for current post (in feed), or whole request (playlist) -- homepage 
		return $this->get_attachments( get_the_ID(), $this->$options['types'] );
	}
	function get_attachments( $parent, $type = null, $count = -1 ) {
		return get_children(array(
			'numberposts' => $count,
			'post_parent' => $parent,
			'post_type' => 'attachment',
			'post_mime_type' => $type,
		));
	}
	function do_feed() {
		if ( false == MyPlugin_PREPEND_ATTACHMENT_IN_FEEDS ) {
			remove_filter('the_content', 'prepend_attachment');
		}
		require_once 'XML/FastCreate.php';
		$this->xml_factory =& XML_FastCreate::factory('Text');		
	}
	function rss2_ns() {
		echo "\n\txmlns:media='http://search.yahoo.com/mrss/'";
	}
	function do_rss_item() {
		$this->comment(__FUNCTION__);
		// get_post_type() requires that $posts[0] is set
		if ( 'attachment' == get_post_type() ) { // Post is attachment
			$this->comment('This post is an attachment');
			if ( $this->mime_type_is_media( get_post_mime_type() ) ) {
				$this->print_media_rss( $GLOBALS['post'], false );
				$this->print_rss_enclosure( $GLOBALS['post'] );
			} else {
				$this->comment( "This attachment is not a media type" );
			}
		} elseif ( $attachments = $this->get_attachments( get_the_ID(), $this->options['types'] ) ) {
			array_walk( $attachments, array( &$this, 'print_media_rss') );
			$this->print_rss_enclosure( array_pop($attachments) );
		} else {
			$this->comment('Post has no media-ish attachments');
		}
	}
	function do_atom_entry(  ) {
		if ( 'attachment' == get_post_type() ) { // Post is attachment
			$this->comment('This post is an attachment');
			if ( $this->mime_type_is_media( get_post_mime_type() ) ) {
				$this->print_atom_enclosure( $GLOBALS['post'] );
			} else {
				$this->comment( "This attachment is not a media type" );
			}
		} elseif ( $attachments = $this->get_attachments( get_the_ID(), $this->options['types'] ) ) {
			array_walk( $attachments, array( &$this, 'print_atom_enclosure') );
		} else {
			$this->comment('Post has no media-ish attachments');
		}
	}
	function print_media_rss( $attachment, $do_description = true ) {
		$this->comment(__FUNCTION__);
		echo $this->xml_factory->_unquote( 
			$this->media_rss_content(
				$attachment
				, $do_description
					? array( $this->media_rss_title($attachment), $this->media_rss_description($attachment) )
					: array()
			));
	}
	function media_rss_content( $attachment, $contents = array() ) {
		return $this->xml_factory->makeXML( 'media:content'
			, array( // attributes
				'type' => get_post_mime_type( $attachment->ID )
				, 'url' => wp_get_attachment_url( $attachment->ID )
				, 'fileSize' => $this->get_attachment_size( $attachment )
				, 'medium' => $this->get_media_medium( $attachment )
			)
			, $contents
		);
	}
	function media_rss_title( $attachment ) {
		return $this->xml_factory->makeXML( 'media:title', array(), array($attachment->post_title) );
	}
	function media_rss_description( $attachment ) {
		return empty($attachment->post_content)
			? null
			: $this->xml_factory->makeXML( 'media:description', array(), array($attachment->post_content) );
	}
	function print_rss_enclosure( $attachment ) {
		$this->comment(__FUNCTION__);
		$this->xml_factory->enclosure( array(
			'type' => get_post_mime_type( $attachment->ID )
			, 'length' => MyPlugin::get_attachment_size( $attachment ) // would need to save as metadata
			, 'url' => wp_get_attachment_url( $attachment->ID )
			));
		echo $this->xml_factory->_unquote( $this->xml_factory->xml );
	}
	function print_atom_enclosure( $attachment ) {
		$this->comment(__FUNCTION__);
		echo $this->xml_factory->_unquote($this->xml_factory->link( array(
			'rel' => 'enclosure'
			, 'type' => get_post_mime_type( $attachment->ID )
			, 'title' => $attachment->post_title
			, 'href' => wp_get_attachment_url( $attachment->ID )
			, 'length' => MyPlugin::get_attachment_size( $attachment )
			)));
	}
	function atom_enclosure( $enclosure ) {
		$this->did_atom_enclosures[] = $enclosure;
		return $enclosure;
	}
	function rss_enclosure( $enclosure ) {
		$this->did_rss_enclosures[] = $enclosure;
		return $enclosure;
	}
	function print_the_xml() { // not used
		echo $this->xml_factory->_unquote( $this->xml_factory->xml );
	}
	function mime_type_is_media( $mime ) {
		foreach ( $this->options['types'] as $type ) {
			if ( false !== strpos( $mime, $type ) )
				return true;
		}
		return false;
	}
	function post_is_media_attachment() {
		return 'attachment' == get_post_type() && $this->mime_type_is_media( get_post_mime_type() );
	}
	function get_media_medium( $attachment ) {
		$mime = explode( '/', $attachment->post_mime_type );
		if ( in_array( $mime[0], $this->media_rss_mediums ) ) {
			return $mime[0];
		} elseif ( function_exists('wp_ext2type') ) {
			$type = wp_ext2type( pathinfo( $attachment->guid, PATHINFO_EXTENSION ) );
			if ( in_array( $type, $this->media_rss_mediums  ) ) {
				return $type;
			}
		}
		return null;
	}
	function get_XML_element( $name, $attributes = null, $contents = null ) {
		$output = "<$name";
		if ( $attributes ) {
			foreach ( $attributes as $attr => $value ) {
				$value = $this->xmlf($value);
				$output .= " $attr='$value'";
			}
		}
		if ( empty($contents) ) {
			$output .= '/>';
		} else {
			$output .= '>';
			if ( is_string($contents) ) {
				$output .= $this->xmlf($contents);
			}
			elseif ( is_array($contents) ) {
				$output .= implode( "\n", $contents );
			}
			$output .= "</$name>";
		}
		return $output;
	}
	function get_attachment_size( $attachment ) {
		return filesize( get_attached_file( $attachment->ID ) );
	}
	function xmlf( $string ) {
		return htmlspecialchars( $string, ENT_QUOTES );
	}
	function comment( $string ) {
		echo '<!-- ' . $string . ' -->';
	}
}

?>