Permalink
Browse files

Re-worked wordpressimport module (Redux)

Signed-off-by: Cam Findlay <cam@camfindlay.com>
  • Loading branch information...
0 parents commit e3a070d4355cad7b31508df1cfe6cc85f5cc705f @camfindlay camfindlay committed Mar 9, 2011
Showing with 315 additions and 0 deletions.
  1. +1 −0 CHANGELOG
  2. +24 −0 LICENSE
  3. +51 −0 README
  4. +4 −0 _config.php
  5. +98 −0 code/WpImporter.php
  6. +129 −0 code/WpParser.php
  7. +8 −0 templates/WpImporter.ss
@@ -0,0 +1 @@
+0.1 Reworked to correctly function with SS 2.4, also now changes image links to work with SS assets folder.
24 LICENSE
@@ -0,0 +1,24 @@
+* Copyright (c) 2008, Silverstripe Ltd.
+* 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 of the <organization> 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 Silverstripe Ltd. ``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 Silverstripe Ltd. 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.
51 README
@@ -0,0 +1,51 @@
+###############################################
+Wordpress Import Module - Redux! (A re-work)
+###############################################
+
+Maintainer Contact
+-----------------------------------------------
+Original Module by:
+Saophalkun Ponlu (Nickname: phalkunz)
+<phalkunz (at) silverstripe (dot) com>
+
+Additional Updates:
+Cam Findlay (Nickname: camfindlay)
+<cam (at) camfindlay.com>
+
+
+Requirements
+-----------------------------------------------
+mod_rewrite
+
+Documentation
+-----------------------------------------------
+
+
+Installation Instructions
+-----------------------------------------------
+
+Usage Overview
+-----------------------------------------------
+It will change any links to uploaded images and
+files in your posts that follow the convention
+"http://yourdomain.com/wp-content/uploads/yyyy/mm/filesname.jpg"
+to "http://yourdomain.com/assets/Uploads/yyyy/mm/filesname.jpg"
+which allows you to migrate you uploaded images
+and files over to SilverStripe while maintaining
+images in your posts.
+
+Add this in your .htaccess file to port old
+wordpress posts in the form /yyyy/mm/name-of-post/
+ to new SilverStripe /blog/name-of-post convention.
+
+<code>
+RewriteRule ^[0-9]{4}/[0-9]{2}/(.*)$ /blog/$1 [R,L]
+</code>
+
+
+
+Known issues:
+-----------------------------------------------
+
+Content can lose a lot of the formatting coming from Wordpress.
+Perhaps parsing the content through a nl2br might help?
@@ -0,0 +1,4 @@
+<?php
+ /* Add wordpress import extension to BlogHolder page type */
+ Object::add_extension('BlogHolder', 'WpImporter');
+?>
@@ -0,0 +1,98 @@
+<?php
+require('WpParser.php');
+
+/*
+ * Decorates a BlogHolder page type, specified in _config.php
+ */
+class WpImporter extends DataObjectDecorator {
+
+ function updateCMSFields(&$fields) {
+ $html_str = '<iframe name="WpImport" src="WpImporter_Controller/index/'.$this->owner->ID.'" width="500"> </iframe>';
+ $fields->addFieldToTab('Root.Content.Import', new LiteralField("ImportIframe",$html_str));
+ }
+}
+
+class WpImporter_Controller extends Controller {
+ // Do security check in case this controller is called by unauthorised user using direct url
+ function init() {
+ parent::init();
+ if(!Permission::check("ADMIN")) Security::permissionFailure();
+ }
+
+ /*
+ * Required
+ */
+ function Link() {
+ return $this->class.'/';
+ }
+
+ /*
+ * Outputs an file upload form
+ */
+ function UploadForm() {
+ return new Form($this, "UploadForm", new FieldSet(
+ new FileField("XMLFile", 'Wordpress XML file'),
+ new HiddenField("BlogHolderID", '', $this->urlParams['ID'])
+ ), new FieldSet(
+ new FormAction('doUpload', 'Import Wordpress XML file')
+ ));
+ }
+
+ function doUpload($data, $form) {
+ // Gets a blog holders ID
+ $blogHolderID = $data['BlogHolderID'];
+
+ // Checks if a file is uploaded
+ if(is_uploaded_file($_FILES['XMLFile']['tmp_name'])) {
+ echo '<p>Processing...<br/></p>';
+ flush();
+ $file = $_FILES['XMLFile'];
+ // check file type. only xml file is allowed
+ if ($file['type'] != 'text/xml') {
+ echo 'Please select Wordpress XML file';
+ die;
+ }
+
+ $wp = new WpParser($file['tmp_name']);
+ $posts = $wp->parse();
+
+ // For testing only
+ // TODO: remove $count
+ //$count = 0;
+ foreach ($posts as $post) {
+ $comments = $post['Comments'];
+ // create a blog entry
+ $entry = new BlogEntry();
+ $entry->ParentID = $blogHolderID;
+ // $posts array and $entry have the same key/field names
+ // so we can use update here.
+
+ $entry->update($post);
+ $entry->write();
+ $entry->publish("Stage", "Live");
+
+ // page comment(s)
+ foreach ($comments as $comment) {
+ $page_comment = new PageComment();
+ $page_comment->ParentID = $entry->ID;
+ $page_comment->update($comment);
+ $page_comment->write();
+ }
+ // count is used for testing only
+ // TODO: remove the next 2 lines
+ //$count++;
+ //if($count==30) break;
+ }
+
+ // delete the temporaray uploaded file
+ unlink($file['tmp_name']);
+ // print sucess message
+ echo 'Complete!<br/>';
+ echo 'Please refresh the admin page to see the new blog entries.';
+ }
+
+
+ }
+
+}
+?>
@@ -0,0 +1,129 @@
+<?php
+/*
+ * WpParser class
+ * Version 0.1
+ * By Saophalkun Ponlu @ Silverstripe
+ *
+ * This class is responsible for parsing Wordpress XML file into array of post entries.
+ * Post entry itself is an array containing entry data
+ * Post entry (array):
+ * Title (mapped to SS blog entry)
+ * Link
+ * Author (mapped to SS blog entry)
+ * Date (mapped to SS blog entry)
+ * UrlTitle
+ * Tags (mapped to SS blog entry)
+ * Content (mapped to SS blog entry)
+ * Comments (array)
+ * Name (mapped to SS blog entry)
+ * Comment (mapped to SS blog entry)
+ * Created (mapped to SS blog entry)
+ */
+class WpParser {
+ private $simple_xml;
+ // xml namespaces
+ private $namespaces;
+ // array of post entries
+ private $posts;
+
+ public function __construct($filename) {
+ $this->simple_xml = simplexml_load_file($filename) or die('Cannot open file.');
+ $this->namespaces = $this->simple_xml->getNamespaces(TRUE);
+
+ }
+
+ /*
+ * Posts getter
+ */
+ public function getPosts() {
+ return $this->posts;
+
+ }
+
+ /*
+ * Parses xml in $simple_xml to array of blog posts
+ * @return array of posts
+ */
+ public function parse() {
+ $sxml = $this->simple_xml;
+ $namespaces = $this->namespaces;
+ $posts = array();
+
+ foreach ($sxml->channel->item as $item) {
+ $post = array();
+ // Get elements in namespaces
+ $wp_ns = $item->children($namespaces['wp']);
+ $content_ns = $item->children($namespaces['content']);
+ $dc_ns = $item->children($namespaces['dc']);
+ //Doesn't seem to like this namespace... remove it for now @TODO - work out wft is going on with that.
+ //$wfw_ns = $item->children($namespaces['wfw']);
+
+ $post['Title'] = (string) $item->title;
+ $post['Link'] = (string) $item->link;
+ $post['Author'] = (string) $dc_ns->creator;
+
+ // Uses this array to check if the category to be added already exists
+ // in the post
+ $categories = array();
+ // Stores all categories and tags of the post in a string var
+ $tags = '';
+
+
+ foreach ($item->category as $cat) {
+ /**
+ * is this in tags or categories? We only want categories to become SS Tags
+ */
+ if($cat['domain'] == "category"){
+
+ if (!in_array($cat, $categories)) {
+ $categories[] = (string)$cat;
+ $tags .= $cat.', ';
+ }
+
+ }//end in category
+
+ }
+
+
+
+ $tags = substr($tags, 0, strlen($tags)-2);
+
+ $post['Tags'] = $tags;
+
+
+
+ /**
+ * change the wp-content link to assets allowing you to migrate images from WP to SS assets folder.
+ */
+ $migrated_content = str_replace('/wp-content/uploads/', '/assets/Uploads', (string)$content_ns->encoded);
+
+
+ $post['Content'] = $migrated_content;
+
+
+
+
+ $post['UrlTitle'] = (string) $wp_ns->post_name;
+ $post['Date'] = (string) $wp_ns->post_date;
+
+ // Array of comments of a post
+ $comments = array();
+ foreach ($wp_ns->comment as $c) {
+ // each comment
+ $comment = array();
+ // $c is not an array but SimpleXML object
+ $comment['Name'] = (string)$c->comment_author;
+ $comment['Comment'] = (string)$c->comment_content;
+ $comment['Created'] = (string)$c->comment_date;
+ $comments[] = $comment;
+ }
+ $post['Comments'] = $comments;
+ $posts[] = $post;
+ }
+ // Also stores posts array in the class
+ // before returning
+ $this->posts = $posts;
+ return $this->posts;
+ }
+}
+?>
@@ -0,0 +1,8 @@
+<html>
+<head>
+<% base_tag %>
+</head>
+<body>
+$UploadForm
+</body>
+</html>

0 comments on commit e3a070d

Please sign in to comment.