Overhauled wordpress importer
authorMarcel Werk <burntime@woltlab.com>
Sun, 2 Oct 2016 14:29:09 +0000 (16:29 +0200)
committerMarcel Werk <burntime@woltlab.com>
Sun, 2 Oct 2016 14:29:09 +0000 (16:29 +0200)
files/lib/system/exporter/WordPress3xExporter.class.php

index 3d6a0262e492686e0f93253fb5b1bf911c2466c8..e104b36de0a566fb4ceb640b42f7b18848d946dd 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\exporter;
+use wcf\data\article\Article;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\importer\ImportHandler;
 use wcf\system\WCF;
@@ -18,34 +19,21 @@ use wcf\util\StringUtil;
 class WordPress3xExporter extends AbstractExporter {
        /**
         * category cache
-        * @var array
+        *
+        * @var        array
         */
        protected $categoryCache = [];
        
        /**
         * @inheritDoc
         */
-       protected $methods = [
-               'com.woltlab.wcf.user' => 'Users',
-               'com.woltlab.blog.category' => 'BlogCategories',
-               'com.woltlab.blog.entry' => 'BlogEntries',
-               'com.woltlab.blog.entry.comment' => 'BlogComments',
-               'com.woltlab.blog.entry.attachment' => 'BlogAttachments'
-       ];
+       protected $methods = ['com.woltlab.wcf.user' => 'Users', 'com.woltlab.wcf.article.category' => 'BlogCategories', 'com.woltlab.wcf.article' => 'BlogEntries', 'com.woltlab.wcf.article.comment' => 'BlogComments', 'com.woltlab.wcf.media' => 'BlogAttachments'];
        
        /**
         * @inheritDoc
         */
        public function getSupportedData() {
-               return [
-                       'com.woltlab.wcf.user' => [
-                       ],
-                       'com.woltlab.blog.entry' => [
-                               'com.woltlab.blog.category',
-                               'com.woltlab.blog.entry.comment',
-                               'com.woltlab.blog.entry.attachment'
-                       ]
-               ];
+               return ['com.woltlab.wcf.user' => [], 'com.woltlab.wcf.article' => ['com.woltlab.wcf.article.category', 'com.woltlab.wcf.article.comment', 'com.woltlab.wcf.media']];
        }
        
        /**
@@ -59,12 +47,12 @@ class WordPress3xExporter extends AbstractExporter {
                        $queue[] = 'com.woltlab.wcf.user';
                }
                
-               // blog
-               if (in_array('com.woltlab.blog.entry', $this->selectedData)) {
-                       if (in_array('com.woltlab.blog.category', $this->selectedData)) $queue[] = 'com.woltlab.blog.category';
-                       $queue[] = 'com.woltlab.blog.entry';
-                       if (in_array('com.woltlab.blog.entry.comment', $this->selectedData)) $queue[] = 'com.woltlab.blog.entry.comment';
-                       if (in_array('com.woltlab.blog.entry.attachment', $this->selectedData)) $queue[] = 'com.woltlab.blog.entry.attachment';
+               // article
+               if (in_array('com.woltlab.wcf.article', $this->selectedData)) {
+                       if (in_array('com.woltlab.wcf.media', $this->selectedData)) $queue[] = 'com.woltlab.wcf.media';
+                       if (in_array('com.woltlab.wcf.article.category', $this->selectedData)) $queue[] = 'com.woltlab.wcf.article.category';
+                       $queue[] = 'com.woltlab.wcf.article';
+                       if (in_array('com.woltlab.wcf.article.comment', $this->selectedData)) $queue[] = 'com.woltlab.wcf.article.comment';
                }
                
                return $queue;
@@ -76,7 +64,7 @@ class WordPress3xExporter extends AbstractExporter {
        public function validateDatabaseAccess() {
                parent::validateDatabaseAccess();
                
-               $sql = "SELECT COUNT(*) FROM ".$this->databasePrefix."posts";
+               $sql = "SELECT COUNT(*) FROM " . $this->databasePrefix . "posts";
                $statement = $this->database->prepareStatement($sql);
                $statement->execute();
        }
@@ -85,7 +73,7 @@ class WordPress3xExporter extends AbstractExporter {
         * @inheritDoc
         */
        public function validateFileAccess() {
-               if (in_array('com.woltlab.blog.entry.attachment', $this->selectedData)) {
+               if (in_array('com.woltlab.wcf.media', $this->selectedData)) {
                        if (empty($this->fileSystemPath) || (!@file_exists($this->fileSystemPath . 'wp-trackback.php'))) return false;
                }
                
@@ -103,43 +91,38 @@ class WordPress3xExporter extends AbstractExporter {
         * Counts users.
         */
        public function countUsers() {
-               return $this->__getMaxID($this->databasePrefix."users", 'ID');
+               return $this->__getMaxID($this->databasePrefix . "users", 'ID');
        }
        
        /**
         * Exports users.
-        * 
-        * @param       integer         $offset
-        * @param       integer         $limit
+        *
+        * @param        integer $offset
+        * @param        integer $limit
         */
        public function exportUsers($offset, $limit) {
                // prepare password update
-               $sql = "UPDATE  wcf".WCF_N."_user
+               $sql = "UPDATE  wcf" . WCF_N . "_user
                        SET     password = ?
                        WHERE   userID = ?";
                $passwordUpdateStatement = WCF::getDB()->prepareStatement($sql);
                
                // get users
                $sql = "SELECT          *
-                       FROM            ".$this->databasePrefix."users
+                       FROM            " . $this->databasePrefix . "users
                        WHERE           ID BETWEEN ? AND ?
                        ORDER BY        ID";
                $statement = $this->database->prepareStatement($sql);
                $statement->execute([$offset + 1, $offset + $limit]);
                while ($row = $statement->fetchArray()) {
-                       $data = [
-                               'username' => $row['user_login'],
-                               'password' => '',
-                               'email' => $row['user_email'],
-                               'registrationDate' => @strtotime($row['user_registered'])
-                       ];
+                       $data = ['username' => $row['user_login'], 'password' => '', 'email' => $row['user_email'], 'registrationDate' => @strtotime($row['user_registered'])];
                        
                        // import user
                        $newUserID = ImportHandler::getInstance()->getImporter('com.woltlab.wcf.user')->import($row['ID'], $data);
                        
                        // update password hash
                        if ($newUserID) {
-                               $passwordUpdateStatement->execute(['phpass:'.$row['user_pass'].':', $newUserID]);
+                               $passwordUpdateStatement->execute(['phpass:' . $row['user_pass'] . ':', $newUserID]);
                        }
                }
        }
@@ -149,7 +132,7 @@ class WordPress3xExporter extends AbstractExporter {
         */
        public function countBlogCategories() {
                $sql = "SELECT  COUNT(*) AS count
-                       FROM    ".$this->databasePrefix."term_taxonomy
+                       FROM    " . $this->databasePrefix . "term_taxonomy
                        WHERE   taxonomy = ?";
                $statement = $this->database->prepareStatement($sql);
                $statement->execute(['category']);
@@ -159,14 +142,14 @@ class WordPress3xExporter extends AbstractExporter {
        
        /**
         * Exports categories.
-        * 
-        * @param       integer         $offset
-        * @param       integer         $limit
+        *
+        * @param        integer $offset
+        * @param        integer $limit
         */
        public function exportBlogCategories($offset, $limit) {
                $sql = "SELECT          term_taxonomy.*, term.name
-                       FROM            ".$this->databasePrefix."term_taxonomy term_taxonomy
-                       LEFT JOIN       ".$this->databasePrefix."terms term
+                       FROM            " . $this->databasePrefix . "term_taxonomy term_taxonomy
+                       LEFT JOIN       " . $this->databasePrefix . "terms term
                        ON              (term.term_id = term_taxonomy.term_id)
                        WHERE           term_taxonomy.taxonomy = ?
                        ORDER BY        term_taxonomy.parent, term_taxonomy.term_id";
@@ -181,19 +164,15 @@ class WordPress3xExporter extends AbstractExporter {
        
        /**
         * Exports the categories recursively.
-        * 
-        * @param       integer         $parentID
+        *
+        * @param        integer $parentID
         */
        protected function exportBlogCategoriesRecursively($parentID = 0) {
                if (!isset($this->categoryCache[$parentID])) return;
                
                foreach ($this->categoryCache[$parentID] as $category) {
-                       ImportHandler::getInstance()->getImporter('com.woltlab.blog.category')->import($category['term_id'], [
-                               'title' => StringUtil::decodeHTML($category['name']),
-                               'parentCategoryID' => $category['parent'],
-                               'showOrder' => 0
-                       ]);
-                               
+                       ImportHandler::getInstance()->getImporter('com.woltlab.wcf.article.category')->import($category['term_id'], ['title' => StringUtil::decodeHTML($category['name']), 'parentCategoryID' => $category['parent'], 'showOrder' => 0]);
+                       
                        $this->exportBlogCategoriesRecursively($category['term_id']);
                }
        }
@@ -203,7 +182,7 @@ class WordPress3xExporter extends AbstractExporter {
         */
        public function countBlogEntries() {
                $sql = "SELECT  COUNT(*) AS count
-                       FROM    ".$this->databasePrefix."posts
+                       FROM    " . $this->databasePrefix . "posts
                        WHERE   post_type = ?";
                $statement = $this->database->prepareStatement($sql);
                $statement->execute(['post']);
@@ -214,19 +193,19 @@ class WordPress3xExporter extends AbstractExporter {
        /**
         * Exports blog entries.
         *
-        * @param       integer         $offset
-        * @param       integer         $limit
+        * @param        integer $offset
+        * @param        integer $limit
         */
        public function exportBlogEntries($offset, $limit) {
                // get entry ids
                $entryIDs = [];
                $sql = "SELECT          ID
-                       FROM            ".$this->databasePrefix."posts
+                       FROM            " . $this->databasePrefix . "posts
                        WHERE           post_type = ?
-                                       AND post_status IN (?, ?, ?, ?, ?, ?)
+                                       AND post_status IN (?, ?, ?, ?, ?)
                        ORDER BY        ID";
                $statement = $this->database->prepareStatement($sql, $limit, $offset);
-               $statement->execute(['post', 'publish', 'pending', 'draft', 'future', 'private', 'trash']);
+               $statement->execute(['post', 'publish', 'pending', 'draft', 'future', 'private']);
                while ($row = $statement->fetchArray()) {
                        $entryIDs[] = $row['ID'];
                }
@@ -239,11 +218,11 @@ class WordPress3xExporter extends AbstractExporter {
                $conditionBuilder->add('term_taxonomy.taxonomy = ?', ['post_tag']);
                $conditionBuilder->add('term.term_id IS NOT NULL');
                $sql = "SELECT          term.name, term_relationships.object_id
-                       FROM            ".$this->databasePrefix."term_relationships term_relationships,
-                                       ".$this->databasePrefix."term_taxonomy term_taxonomy
-                       LEFT JOIN       ".$this->databasePrefix."terms term
+                       FROM            " . $this->databasePrefix . "term_relationships term_relationships,
+                                       " . $this->databasePrefix . "term_taxonomy term_taxonomy
+                       LEFT JOIN       " . $this->databasePrefix . "terms term
                        ON              (term.term_id = term_taxonomy.term_id)
-                       ".$conditionBuilder;
+                       " . $conditionBuilder;
                $statement = $this->database->prepareStatement($sql);
                $statement->execute($conditionBuilder->getParameters());
                while ($row = $statement->fetchArray()) {
@@ -258,9 +237,9 @@ class WordPress3xExporter extends AbstractExporter {
                $conditionBuilder->add('term_relationships.object_id IN (?)', [$entryIDs]);
                $conditionBuilder->add('term_taxonomy.taxonomy = ?', ['category']);
                $sql = "SELECT          term_taxonomy.term_id, term_relationships.object_id
-                       FROM            ".$this->databasePrefix."term_relationships term_relationships,
-                                       ".$this->databasePrefix."term_taxonomy term_taxonomy
-                       ".$conditionBuilder;
+                       FROM            " . $this->databasePrefix . "term_relationships term_relationships,
+                                       " . $this->databasePrefix . "term_taxonomy term_taxonomy
+                       " . $conditionBuilder;
                $statement = $this->database->prepareStatement($sql);
                $statement->execute($conditionBuilder->getParameters());
                while ($row = $statement->fetchArray()) {
@@ -273,31 +252,19 @@ class WordPress3xExporter extends AbstractExporter {
                $conditionBuilder->add('post.ID IN (?)', [$entryIDs]);
                
                $sql = "SELECT          post.*, user.user_login
-                       FROM            ".$this->databasePrefix."posts post
-                       LEFT JOIN       ".$this->databasePrefix."users user
+                       FROM            " . $this->databasePrefix . "posts post
+                       LEFT JOIN       " . $this->databasePrefix . "users user
                        ON              (user.ID = post.post_author)
-                       ".$conditionBuilder;
+                       " . $conditionBuilder;
                $statement = $this->database->prepareStatement($sql);
                $statement->execute($conditionBuilder->getParameters());
                while ($row = $statement->fetchArray()) {
-                       $additionalData = [];
-                       if (isset($tags[$row['ID']])) $additionalData['tags'] = $tags[$row['ID']];
-                       if (isset($categories[$row['ID']])) $additionalData['categories'] = $categories[$row['ID']];
-                       
                        $time = @strtotime($row['post_date_gmt']);
                        if (!$time) $time = @strtotime($row['post_date']);
                        
-                       ImportHandler::getInstance()->getImporter('com.woltlab.blog.entry')->import($row['ID'], [
-                               'userID' => $row['post_author'] ?: null,
-                               'username' => $row['user_login'] ?: '',
-                               'subject' => $row['post_title'],
-                               'message' => self::fixMessage($row['post_content']),
-                               'time' => $time,
-                               'comments' => $row['comment_count'],
-                               'enableHtml' => 1,
-                               'isPublished' => ($row['post_status'] == 'publish') ? 1 : 0,
-                               'isDeleted' => ($row['post_status'] == 'trash') ? 1 : 0
-                       ], $additionalData);
+                       $additionalData = ['contents' => [0 => ['title' => $row['post_title'], 'content' => self::fixMessage($row['post_content']), 'tags' => (isset($tags[$row['ID']]) ? $tags[$row['ID']] : [])]]];
+                       
+                       ImportHandler::getInstance()->getImporter('com.woltlab.wcf.article')->import($row['ID'], ['userID' => $row['post_author'] ?: null, 'username' => $row['user_login'] ?: '', 'time' => $time, 'categoryID' => (isset($categories[$row['ID']]) ? reset($categories[$row['ID']]) : null), 'comments' => $row['comment_count'], 'publicationStatus' => ($row['post_status'] == 'publish') ? Article::PUBLISHED : Article::UNPUBLISHED], $additionalData);
                }
        }
        
@@ -306,7 +273,7 @@ class WordPress3xExporter extends AbstractExporter {
         */
        public function countBlogComments() {
                $sql = "SELECT  COUNT(*) AS count
-                       FROM    ".$this->databasePrefix."comments
+                       FROM    " . $this->databasePrefix . "comments
                        WHERE   comment_approved = ?";
                $statement = $this->database->prepareStatement($sql);
                $statement->execute([1]);
@@ -317,32 +284,25 @@ class WordPress3xExporter extends AbstractExporter {
        /**
         * Exports blog comments.
         *
-        * @param       integer         $offset
-        * @param       integer         $limit
+        * @param        integer $offset
+        * @param        integer $limit
         */
        public function exportBlogComments($offset, $limit) {
                $sql = "SELECT  comment_ID, comment_parent
-                       FROM    ".$this->databasePrefix."comments
+                       FROM    " . $this->databasePrefix . "comments
                        WHERE   comment_ID = ?";
                $parentCommentStatement = $this->database->prepareStatement($sql, $limit, $offset);
                
                $sql = "SELECT          *
-                       FROM            ".$this->databasePrefix."comments
+                       FROM            " . $this->databasePrefix . "comments
                        WHERE   comment_approved = ?
                        ORDER BY        comment_parent, comment_ID";
                $statement = $this->database->prepareStatement($sql, $limit, $offset);
                $statement->execute([1]);
                while ($row = $statement->fetchArray()) {
                        if (!$row['comment_parent']) {
-                               ImportHandler::getInstance()->getImporter('com.woltlab.blog.entry.comment')->import($row['comment_ID'], [
-                                       'objectID' => $row['comment_post_ID'],
-                                       'userID' => $row['user_id'] ?: null,
-                                       'username' => $row['comment_author'],
-                                       'message' => StringUtil::decodeHTML($row['comment_content']),
-                                       'time' => @strtotime($row['comment_date_gmt'])
-                               ]);
-                       }
-                       else {
+                               ImportHandler::getInstance()->getImporter('com.woltlab.wcf.article.comment')->import($row['comment_ID'], ['userID' => $row['user_id'] ?: null, 'username' => $row['comment_author'], 'message' => StringUtil::decodeHTML($row['comment_content']), 'time' => @strtotime($row['comment_date_gmt'])], ['articleID' => $row['comment_post_ID']]);
+                       } else {
                                $parentID = $row['comment_parent'];
                                
                                do {
@@ -350,13 +310,7 @@ class WordPress3xExporter extends AbstractExporter {
                                        $row2 = $parentCommentStatement->fetchArray();
                                        
                                        if (!$row2['comment_parent']) {
-                                               ImportHandler::getInstance()->getImporter('com.woltlab.blog.entry.comment.response')->import($row['comment_ID'], [
-                                                       'commentID' => $row2['comment_ID'],
-                                                       'userID' => $row['user_id'] ?: null,
-                                                       'username' => $row['comment_author'],
-                                                       'message' => StringUtil::decodeHTML($row['comment_content']),
-                                                       'time' => @strtotime($row['comment_date_gmt'])
-                                               ]);
+                                               ImportHandler::getInstance()->getImporter('com.woltlab.wcf.article.comment.response')->import($row['comment_ID'], ['commentID' => $row2['comment_ID'], 'userID' => $row['user_id'] ?: null, 'username' => $row['comment_author'], 'message' => StringUtil::decodeHTML($row['comment_content']), 'time' => @strtotime($row['comment_date_gmt'])]);
                                                break;
                                        }
                                        $parentID = $row2['comment_parent'];
@@ -366,17 +320,16 @@ class WordPress3xExporter extends AbstractExporter {
                }
        }
        
-
        /**
         * Counts blog attachments.
         */
        public function countBlogAttachments() {
                $sql = "SELECT          COUNT(*) AS count
-                       FROM            ".$this->databasePrefix."posts
+                       FROM            " . $this->databasePrefix . "posts
                        WHERE           post_type = ?
                                        AND post_parent IN (
                                                SELECT  ID
-                                               FROM    ".$this->databasePrefix."posts  
+                                               FROM    " . $this->databasePrefix . "posts      
                                                WHERE   post_type = ?
                                                        AND post_status IN (?, ?, ?, ?, ?, ?)
                                        )";
@@ -389,18 +342,18 @@ class WordPress3xExporter extends AbstractExporter {
        /**
         * Exports blog attachments.
         *
-        * @param       integer         $offset
-        * @param       integer         $limit
+        * @param        integer $offset
+        * @param        integer $limit
         */
        public function exportBlogAttachments($offset, $limit) {
                $sql = "SELECT          posts.*, postmeta.*
-                       FROM            ".$this->databasePrefix."posts posts
-                       LEFT JOIN       ".$this->databasePrefix."postmeta postmeta
+                       FROM            " . $this->databasePrefix . "posts posts
+                       LEFT JOIN       " . $this->databasePrefix . "postmeta postmeta
                        ON              (postmeta.post_id = posts.ID AND postmeta.meta_key = ?)
                        WHERE           post_type = ?
                                        AND post_parent IN (
                                                SELECT  ID
-                                               FROM    ".$this->databasePrefix."posts
+                                               FROM    " . $this->databasePrefix . "posts
                                                WHERE   post_type = ?
                                                        AND post_status IN (?, ?, ?, ?, ?, ?)
                                        )
@@ -408,38 +361,56 @@ class WordPress3xExporter extends AbstractExporter {
                $statement = $this->database->prepareStatement($sql, $limit, $offset);
                $statement->execute(['_wp_attached_file', 'attachment', 'post', 'publish', 'pending', 'draft', 'future', 'private', 'trash']);
                while ($row = $statement->fetchArray()) {
-                       $fileLocation = $this->fileSystemPath.'wp-content/uploads/'.$row['meta_value'];
+                       $fileLocation = $this->fileSystemPath . 'wp-content/uploads/' . $row['meta_value'];
                        
-                       $isImage = 0;
+                       $isImage = $width = $height = 0;
                        if ($row['post_mime_type'] == 'image/jpeg' || $row['post_mime_type'] == 'image/png' || $row['post_mime_type'] == 'image/gif') $isImage = 1;
+                       if ($isImage) {
+                               list($width, $height) = getimagesize($fileLocation);
+                       }
                        
                        $time = @strtotime($row['post_date_gmt']);
                        if (!$time) $time = @strtotime($row['post_date']);
                        
-                       ImportHandler::getInstance()->getImporter('com.woltlab.blog.entry.attachment')->import($row['meta_id'], [
-                               'objectID' => $row['post_parent'],
-                               'userID' => $row['post_author'] ?: null,
-                               'filename' => basename($fileLocation),
-                               'filesize' => filesize($fileLocation),
-                               'fileType' => $row['post_mime_type'],
-                               'isImage' => $isImage,
-                               'downloads' => 0,
-                               'lastDownloadTime' => 0,
-                               'uploadTime' => $time,
-                               'showOrder' => 0
-                       ], ['fileLocation' => $fileLocation]);
+                       ImportHandler::getInstance()->getImporter('com.woltlab.wcf.media')->import($row['ID'], ['filename' => basename($fileLocation), 'filesize' => filesize($fileLocation), 'fileType' => $row['post_mime_type'], 'fileHash' => md5_file($fileLocation), 'uploadTime' => $time, 'userID' => $row['post_author'] ?: null, 'isImage' => $isImage, 'width' => $width, 'height' => $height], ['fileLocation' => $fileLocation, 'contents' => []]);
                }
        }
        
        /**
         * Returns message with fixed syntax as used in WCF.
-        * 
-        * @param       string          $string
-        * @return      string
+        *
+        * @param        string $string
+        * @return        string
         */
        private static function fixMessage($string) {
                $string = str_replace("\n", "<br />\n", StringUtil::unifyNewlines($string));
                
+               // replace media
+               $string = preg_replace_callback('~<img class="([^"]*wp-image-(\d+)[^"]*)".*?>~is', function ($matches) {
+                       $mediaID = ImportHandler::getInstance()->getNewID('com.woltlab.wcf.media', $matches[2]);
+                       if (!$mediaID) {
+                               return $matches[0];
+                       } 
+                               
+                       $alignment = 'none';
+                       if (strpos($matches[1], 'alignleft')) {
+                               $alignment = 'left';
+                       } else if (strpos($matches[1], 'alignright')) $alignment = 'right';
+                       
+                       $size = null;
+                       if (strpos($matches[1], 'size-thumbnail')) {
+                               $size = 'small';
+                       } else {
+                               if (strpos($matches[1], 'size-medium')) {
+                                       $size = 'medium';
+                               } else if (strpos($matches[1], 'size-large')) $size = 'large';
+                       }
+                       
+                       $data = [$mediaID, $size, $alignment];
+                       
+                       return '<woltlab-metacode data-name="wsm" data-attributes="' . base64_encode(json_encode($data)) . '"></woltlab-metacode>';
+               }, $string);
+               
                return $string;
        }
-}
+}