freemarconi
Forum Replies Created
-
Forum: Your WordPress
In reply to: XML data feed importI too wanted to be able to do this, but couldn’t find anything. So I went to making my own plugin, despite having extremely limited PHP programming skills. Below is what I finally came up with that seems to work. Sorry for the length, I commented it heavily so you could see what I was doing. Like I said, I don’t know much about programming, so I apologize for the likely numerous bad practices – it also has no admin screen functionality so you’re stuck with editing the code itself to get what you want. When you’re done, save it to a php file and stick it in your plugins folder. Upon activation, it should create any posts from the uri you put in, and setup an hourly scheduled event to look for future posts. That’s all! I can’t guarantee it will work for you, and probably can’t help you if it doesn’t lol. But hopefully it will at least start you out.
<?php /* * Plugin Name: XML to WordPress Posts * Description: Creates posts automatically from an XML feed. * Author: Terry Hart * Plugin URI: http://www.freemarconi.com * Version: 1.0 * ======================================================================= */ /* The following code is probably not very pretty or efficient, but it's working * for me so far. I am not a PHP programmer! This took me forever to get going lol. * A lot is taken from the RSS_Import class in the WordPress core, much of the rest * from looking at other plugins and scouring the web for help. * I can't guarantee anything! But hopefully someone can get something out of the * days I spent getting this to work, especially since there doesn't seem to be * any existing plugins that do quite what this does yet. */ require_once(ABSPATH . '/wp-admin/includes/post.php'); require_once(ABSPATH . '/wp-admin/includes/taxonomy.php'); require_once(ABSPATH . '/wp-admin/includes/import.php'); if (!class_exists("xmltowp")) { class xmltowp { var $posts = array (); var $sxml; function xmltowp() { //constructor } function xmltowp_init() { $this->import(); } function get_posts() { global $wpdb; $xmluri = 'http://PUT YOUR FEED ADDRESS HERE'; $sxml = simplexml_load_file($xmluri); $index = 0; /* This next part depends on the schema of your XML * (Sorry if I didn't use those words correctly, I'm * not entirely sure what it means) And the format of the feed * For example, if you look at the XML from a Google * Calendars feed, you'll see xmlns:gd='http://schemas.google.com/g/2005' * at the top, and each entry is enclosed with <entry> tags. * The next two lines would be: * foreach ($sxml->entry as $entry) { * $gd = $entry->children('http://schemas.google.com/g/2005'); * * For my site, and the example below, I pulled an RSS feed, * so the next two lines differ to reflect the structure and schema of * that type of feed. */ foreach ($sxml->channel->item as $item) { $dc = $item->children('http://purl.org/dc/elements/1.1/'); /* Now you have to get all the information you want from the XML * document. The format depends on the XML tags used. * For plain tags - <TAG>, you would use the format * $string = $item->TAG; * (or $entry instead of $item depending on your schema/structure) * Some data is enclosed by <dc:TAG> (or <gd:TAG>) tags, * Those can be parsed by using * $string = $dc->TAG; * Finally, some data is in the tag itself, like * <enclosure url="http://ccmixter.org/content/4nsic/4nsic_-_Super_Heroes_(_Sol_Remix).mp3" length="3958953" type="audio/mpeg"></enclosure> * Parsing that requires something like * $string = $item->TAG->attributes()->ATTRIBUTE; * * For WordPress posts, you'll eventually need the following strings: * $post_author, $post_date, $post_date_gmt, $post_content, $post_title, $post_status, $guid, and $categories * First, let's get everything we want out of the XML itself, then we'll play with it a bit. * This is an example of what I wrote for my own site freemarconi.com. I uploaded vocal tracks * of our music to ccMixter.org. The site has an API that lets you pull an XML document showing * everyone who has remixed my tracks. I wanted to create a post for every remix made * and make it look pretty. Hopefully you get an idea of how this is working to make your * own plugin. */ $post_title = $item->title; //I'm taking the title exactly as it comes. You may want to process your own titles a bit for aesthetic reasons $guid = $item->link; //Also taken straight. I don't know what $guid is for, but I want the link for the post content $pubDate = $item->pubDate; //We'll process this into the two required date fields in a bit $post_content = $item->description; //This starts our post content out, we'll be playing with this later $creator = $dc->creator; //Extra field I want to add into the content $mp3file = $item->enclosure->attributes()->url; //Same //Get the date $post_date_gmt = strtotime($pubDate); $post_date_gmt = gmdate('Y-m-d H:i:s', $post_date_gmt); $post_date = get_date_from_gmt( $post_date_gmt ); /* I had a separate function that generated the category I wanted the post to appear in * which I didn't include here. If you don't have anything for categories it defaults to * uncategorized. If you want every post from the XML going to the same category, just * declare $categories as a string containing your category name. If the category doesn't * exist, WordPress will create it. */ $categories = $source_song; /* This is how I created the actual post content. Remember, I took the <description> from the * XML, which makes the bulk of what I want the post to say. The rest I set below in a number * of strings, which we'll piece together next. */ //Format the post content and add mp3 to Audio Player $post_content_title = '<p><a href="' . $guid . '" target="_blank">' . $post_title . '</a></p>'; $post_content_creator = '<p>By ' . $creator . '</p>'; $post_content_listen = '</p><p> [audio:'. $mp3file . '] </p>'; // Clean up content $post_content = preg_replace_callback('|<(/?[A-Z]+)|', create_function('$match', 'return "<" . strtolower($match[1]);'), $post_content); $post_content = str_replace('<br />', '<br />', $post_content); $post_content = str_replace('<hr>', '<hr />', $post_content); // I put all my content pieces together into $post_content $post_content = $post_content_title . $post_content_creator . $post_content . $post_content_listen; $post_author = 1; //This makes my posts show 'admin' as the author, which is fine for me. You might be able to use a variable or string here instead, I don't know how it works if the user doesn't exist in the WP Database yet though! $post_status = 'publish'; //I don't know the other statuses available, probably something like 'draft' etc. That would be good if you want a chance to review posts before they go live on your site $this->posts[$index] = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_status', 'guid', 'categories'); //And we have our array that the other functions will put into the posts table $index++; } } //Shouldn't have to change anything in these next two functions function import_posts() { foreach ($this->posts as $post) { extract($post); if ($post_id = post_exists($post_title, $post_content, $post_date)) { return; } else { $post_id = wp_insert_post($post); if ( is_wp_error( $post_id ) ) return $post_id; if (!$post_id) { return; } if (0 != count($categories)) wp_create_categories($categories, $post_id); } } } function import() { $file = $sxml; if ( isset($file['error']) ) { echo $file['error']; return; } $this->file = $file['file']; $this->get_posts(); $result = $this->import_posts(); if ( is_wp_error( $result ) ) return $result; wp_import_cleanup($file['id']); do_action('import_done', 'rss'); } } } if (class_exists("xmltowp")) { $xmltowp_plugin = new xmltowp(); } //Actions and Filters if (isset($xmltowp_plugin)) { //Actions register_activation_hook( __FILE__, array(&$xmltowp_plugin, 'xmltowp_init' )); if (!wp_next_scheduled('xmlschedule_hook')) { wp_schedule_event( time(), 'hourly', 'xmlschedule_hook' ); //Besides 'hourly', you can also schedule 'daily' or 'twicedaily'. } add_action( 'xmlschedule_hook', array(&$xmltowp_plugin, 'xmltowp_init' )); //I don't have a deactivation hook to remove the scheduled event, boh! } ?>