* @author Michael Frumin * @copyright ©2004 Michael Frumin, Michal Migurski * @link http://reblog.org Reblog * @link http://feedonfeeds.com Feed On Feeds * @version $Revision: 1.2 $ */ /** * MetaWeblog_API is a plug-in for refeed. * * This plug-in implements a connection to the Metaweblog API, * notably used by WordPress and MSN Spaces blogging software. * Published items are pushed into a live blog via the API, and * common modifications performed via the RF_Userdata_Controller * object are also reflected. * * @see RF_Controller::loadPlugins() * @see RF_Controller::invokePlugin() * @see http://www.xmlrpc.com/metaWeblogApi * @package Plugins */ class MetaWeblog_API { /** * This variable must be set to boolean true for thise class to be * an active plug-in. * * @var boolean * @see RF_Controller::loadPlugins() */ var $activePlugin = true; /** * Reference to operative controller object. * @var RF_Controller */ var $controller; /** * Path to XML RPC endpoint * * If your WordPress blog is located at "http://example.com/blog/", * this variable would be "http://example.com/blog/xmlrpc.php". * * For MSN Spaces, this should always be * "https://storage.msn.com/storageservice/MetaWeblog.rpc". * You will need to have OpenSSL support compiled into your PHP installation. * * If you want to publish to multiple blogs, make this an array of XML RPC endpoints. * * @var string */ var $url = 'http://www.mysite.org/reblog/xmlrpc.php'; /** * Array of categories for the published items * associated array based on expected tag names in RF * * For wordpress, if you specify a category which is not present in your blog, * the item will also show up in the default category (aside other categories) */ var $categories = array('civic' => 'Civic Engagement', 'credibility' => 'Credibility', 'games' => 'Ecology of Games', 'identity' => 'Identity', 'race' =>'Race and Ethnicity'); /** * Blog ID for blog * * For WordPress, this value appears meaningless, and probably shouldn't be changed. * * For MSN Spaces, this value should be "MyBlog". * * If you want to publish to multiple blogs, make this an array of Blog ID's. * * @var int */ var $blog = 1; /** * Administrative username for blog * * For MSN Spaces, this should be the part of your blog URL after * "member", e.g. "http://spaces.msn.com/members/username" * * If you want to publish to multiple blogs, make this an array of usernames. * * @var string */ var $username = 'admin'; /** * Administrative password for blog * * For MSN Spaces, this should be the "secret word" you specify * when setting up E-Mail Publishing in your settings. * * If you want to publish to multiple blogs, make this an array of passwords. * * @var string */ var $password = 'nmc4200'; /** * Array of MetaWeblog_Blog's * @var array */ var $blogs = array(); /** * @param RF_Controller $controller - * * @uses MetaWeblog_API::$controller Assigned on instantiation, from {@link RF_Controller $controller}. * @uses MetaWeblog_API::$blogs Assigned based on values of $url, $blog, $username and $password */ function MetaWeblog_API(&$controller) { $this->controller =& $controller; $urls = (array) $this->url; $blog_ids = (array) $this->blog; $usernames = (array) $this->username; $passwords = (array) $this->password; $blogs = min(count($urls), count($blog_ids), count($usernames), count($passwords)); foreach(range(0, $blogs - 1) as $b) { $blog = new MetaWeblog_Blog($urls[$b], $blog_ids[$b], $usernames[$b], $passwords[$b]); $this->blogs[$blog->toString()] = $blog; } } /** * Generate struct of item for MetaWeblog API * * @param RF_Item $item - * @return array Associative array of item properties, as described by MetaWeblog API * * @uses MetaWeblog_API::itemTitle() * @uses MetaWeblog_API::itemDescription() * @see http://www.xmlrpc.com/metaWeblogApi */ function itemStruct(&$item) { return array('title' => $this->itemTitle($item), 'description' => $this->itemDescription($item), // add category code ahl 'categories' => $this->itemCategories($item), ); } /** * Generate title of item for remote weblog * * @param RF_Item $item - * @return string Item title */ function itemTitle(&$item) { return $item->title; } /** * Generate description of item for remote weblog * * @param RF_Item $item - * @return string Item description, may contain HTML */ function itemDescription(&$item) { $view =& $GLOBALS['REBLOG_VIEW']; $view->assign('item', $item); $view->assign('tag', 'p'); return (empty($item->content) ? '' : $item->content) .(empty($item->metadata['comment']) ? '' : "

{$item->metadata['comment']}

") .'

'.htmlspecialchars($item->title).'

' .preg_replace('/\s+/', ' ', $view->fetch('out/original_item.tpl')); } /** * Generate categories of item for remote weblog * * @param RF_Item $item - * @return array Array of categories for this item * */ function itemCategories(&$item) { // convert tags to array $mytags = explode(',', $item->category); // build an array of mapped categories for output foreach ($mytags as $usertag) { $postcategories[] = $this->categories[$usertag]; } return $postcategories; } /** * Post item to remote weblog. * * @param RF_User $user - * @param RF_Item $item - * @return string Unique ID of post in remote weblog */ function sendPost(&$user, &$item) { $args = array('item' => $item->getID(), 'metadata' => array(array('format' => 'long', 'label' => 'metaweblog_posts'), array('format' => 'long', 'label' => 'comment'), array('format' => 'numeric', 'label' => 'self'))); $item = reset($this->controller->getUserItems($user, $args)); // this is a serialized array of weblog post ID's. The keys in the // array are string values of MetaWeblog_Blog objects. $post_ids = unserialize($item->metadata['metaweblog_posts']); foreach($this->blogs as $b => $blog) { if(isset($post_ids[$b])) { $parameters = array($post_ids[$b], $blog->username, $blog->password); $post = $blog->call('metaWeblog.getPost', $parameters); if(empty($post)) unset($post_ids[$b]); } $response = isset($post_ids[$b]) ? $blog->call('metaWeblog.editPost', array($post_ids[$b], $blog->username, $blog->password, $this->itemStruct($item), $item->published ? true : false)) : $blog->call('metaWeblog.newPost', array($blog->blog_id, $blog->username, $blog->password, $this->itemStruct($item), $item->published ? true : false)); if(isset($post_ids[$b])) continue; if($post_id = $response) $post_ids[$b] = $post_id; } $this->controller->setItemUserdata($item, $user, 'metaweblog_posts', array(serialize($post_ids)), 'long'); } function markedItemPublished(&$user, &$item) { $this->sendPost($user, $item); } function markedItemsPublished(&$user, &$items) { foreach($items as $item) $this->sendPost($user, $item); } function markedItemUnpublished(&$user, &$item) { $this->sendPost($user, $item); } function markedItemsUnpublished(&$user, &$items) { foreach($items as $item) $this->sendPost($user, $item); } function postedItem(&$user, &$item) { $this->sendPost($user, $item); } function setItemCommentTags(&$user, &$item, &$comment, &$tags) { $item = $this->controller->getUserItem($user, $item); $this->sendPost($user, $item, $item->published ? true : false); } function setItemTitleContentLink(&$user, &$item, &$title, &$content, &$link) { $item = $this->controller->getUserItem($user, $item); $this->sendPost($user, $item, $item->published ? true : false); } function setItemLink(&$user, &$item, &$link) { $item = $this->controller->getUserItem($user, $item); $this->sendPost($user, $item, $item->published ? true : false); } function menuMessageHTML() { $blogs = array(); foreach($this->blogs as $blog) { $parameters = array($blog->blog_id, $blog->username, $blog->password); $blogs = array_merge($blogs, $blog->call('blogger.getUsersBlogs', $parameters)); } $html = '

Remote Weblogs

Content published to:

'; foreach($blogs as $blog) $html .= '

linkNewWindows() ? 'target="_blank"' : '') . '>' . htmlspecialchars($blog['blogName']) . '

'; return $html; } } /** * MetaWeblog_Blog holds a set of configuration settings for one remote blog. * * @see http://www.xmlrpc.com/metaWeblogApi * @package Plugins */ class MetaWeblog_Blog { /** * Path to XML RPC endpoint * @link MetaWeblog_API::$url * @var string */ var $url; /** * Blog ID for blog * @link MetaWeblog_API::$blog * @var int */ var $blog_id; /** * Administrative username for blog * @link MetaWeblog_API::$username * @var string */ var $username; /** * Administrative password for blog * @link MetaWeblog_API::$password * @var string */ var $password; /** * @param string $url {@link MetaWeblog_Blog::$url Assigned from $url} * @param string $blog_id {@link MetaWeblog_Blog::$blog_id Assigned from $blog_id} * @param string $username {@link MetaWeblog_Blog::$username Assigned from $username} * @param string $password {@link MetaWeblog_Blog::$password Assigned from $password} */ function MetaWeblog_Blog($url, $blog_id, $username, $password) { $this->url = $url; $this->blog_id = $blog_id; $this->username = $username; $this->password = $password; } /** * Make a call to remote weblog via RPC * * @param string $method Name of RPC method * @param array $parameters Array of parameters to pass * @return mixed Response from remote procedure * * @uses MetaWeblog_API_Blog::$url */ function call($method, $parameters) { require_once 'XML/RPC.php'; extract(parse_url($this->url)); $message = new XML_RPC_Message($method, array_map('XML_RPC_encode', $parameters)); $client = new XML_RPC_Client($path, $host, ($scheme == 'https' ? 443 : 80)); $response = $client->send($message); return empty($response) || is_null($response->value()) ? null : XML_RPC_decode($response->value()); } /** * @return string This instance as a string suitable for use as a unique key. */ function toString() { return join(':', array($this->url, $this->blog_id, md5($this->username.$this->password))); } } ?>