diff --git a/code/compat/pages/BlogEntry.php b/code/compat/pages/BlogEntry.php deleted file mode 100644 index 7068752..0000000 --- a/code/compat/pages/BlogEntry.php +++ /dev/null @@ -1,112 +0,0 @@ - 'SS_Datetime', - 'Author' => 'Text', - 'Tags' => 'Text', - ); - - /** - * {@inheritdoc} - */ - public function canCreate($member = null) { - return false; - } - - /** - * {@inheritdoc} - */ - public function up() { - - //Migrate comma separated tags into BlogTag objects. - foreach($this->TagNames() as $tag) { - - $existingTag = BlogTag::get()->filter(array('Title' => $tag, 'BlogID' => $this->ParentID)); - if($existingTag->count()) { - //if tag already exists we will simply add it to this post. - $tagObject = $existingTag->First(); - - } else { - - //if the tag is now we create it and add it to this post. - $tagObject = new BlogTag(); - $tagObject->Title = $tag; - $tagObject->BlogID = $this->ParentID; - $tagObject->write(); - - - } - - if($tagObject){ - $this->Tags()->add($tagObject); - } - } - - //Store if the original entity was published or not (draft) - $published = $this->IsPublished(); - // If a user has subclassed BlogEntry, it should not be turned into a BlogPost. - if($this->ClassName === 'BlogEntry') { - $this->ClassName = 'BlogPost'; - $this->RecordClassName = 'BlogPost'; - } - //Migrate these key data attributes - $this->PublishDate = $this->Date; - $this->AuthorNames = $this->Author; - $this->InheritSideBar = true; - - //Write and additionally publish the item if it was published before. - $this->write(); - if($published){ - $this->publish('Stage','Live'); - $message = "PUBLISHED: "; - } else { - $message = "DRAFT: "; - } - - return $message . $this->Title; - } - - /** - * Safely split and parse all distinct tags assigned to this BlogEntry. - * - * @deprecated since version 2.0 - * - * @return array - */ - public function TagNames() { - $tags = preg_split('/\s*,\s*/', trim($this->Tags)); - - $results = array(); - - foreach($tags as $tag) { - if($tag) $results[mb_strtolower($tag)] = $tag; - } - - return $results; - } - -} - -/** - * @deprecated since version 2.0 - */ -class BlogEntry_Controller extends BlogPost_Controller { - -} diff --git a/code/compat/pages/BlogHolder.php b/code/compat/pages/BlogHolder.php deleted file mode 100644 index 86b8cdd..0000000 --- a/code/compat/pages/BlogHolder.php +++ /dev/null @@ -1,73 +0,0 @@ - 'Boolean', - 'ShowFullEntry' => 'Boolean', - ); - - /** - * @var array - */ - private static $has_one = array( - 'Owner' => 'Member', - ); - - /** - * {@inheritdoc} - */ - public function canCreate($member = null) { - return false; - } - - - //Overload these to stop the Uncaught Exception: Object->__call(): the method 'parent' does not exist on 'BlogHolder' error. - public function validURLSegment() { - return true; - } - public function syncLinkTracking() { - return null; - } - - /** - * {@inheritdoc} - */ - public function up() { - - $published = $this->IsPublished(); - - if($this->ClassName === 'BlogHolder') { - $this->ClassName = 'Blog'; - $this->RecordClassName = 'Blog'; - $this->PostsPerPage = 10; - $this->write(); - } - - if($published){ - $this->publish('Stage','Live'); - $message = "PUBLISHED: "; - } else { - $message = "DRAFT: "; - } - - return $message . $this->Title; - } -} - -/** - * @deprecated since version 2.0 - */ -class BlogHolder_Controller extends BlogTree_Controller { - -} diff --git a/code/compat/pages/BlogTree.php b/code/compat/pages/BlogTree.php deleted file mode 100644 index 9c72681..0000000 --- a/code/compat/pages/BlogTree.php +++ /dev/null @@ -1,53 +0,0 @@ - 'Varchar(255)', - 'LandingPageFreshness' => 'Varchar', - ); - - /** - * {@inheritdoc} - */ - public function canCreate($member = null) { - return false; - } - - /** - * {@inheritdoc} - */ - public function up() { - $published = $this->IsPublished(); - if($this->ClassName === 'BlogTree') { - $this->ClassName = 'Page'; - $this->RecordClassName = 'Page'; - $this->write(); - } - if($published){ - $this->publish('Stage','Live'); - $message = "PUBLISHED: "; - } else { - $message = "DRAFT: "; - } - - return $message . $this->Title; - } -} - -/** - * @deprecated since version 2.0 - */ -class BlogTree_Controller extends Page_Controller { - -} diff --git a/code/compat/tasks/BlogMigrationTask.php b/code/compat/tasks/BlogMigrationTask.php deleted file mode 100644 index d222633..0000000 --- a/code/compat/tasks/BlogMigrationTask.php +++ /dev/null @@ -1,89 +0,0 @@ -message('Migrating legacy blog records'); - - foreach($classes as $class) { - - $this->upClass($class); - } - - } - - /** - * @param string $text - */ - protected function message($text) { - if(Controller::curr() instanceof DatabaseAdmin) { - DB::alteration_message($text, 'obsolete'); - } else { - echo $text . "
"; - } - } - - /** - * Migrate records of a single class - * - * @param string $class - * @param null|string $stage - */ - protected function upClass($class) { - if(!class_exists($class)) { - return; - } - - if(is_subclass_of($class, 'SiteTree')) { - $items = SiteTree::get()->filter('ClassName', $class); - } else { - $items = $class::get(); - } - - if($count = $items->count()) { - $this->message( - sprintf( - 'Migrating %s legacy %s records.', - $count, - $class - ) - ); - - foreach($items as $item) { - $cancel = $item->extend('onBeforeUp'); - - if($cancel && min($cancel) === false) { - continue; - } - - /** - * @var MigratableObject $item - */ - $result = $item->up(); - $this->message($result); - - $item->extend('onAfterUp'); - } - } - } - - /** - * {@inheritdoc} - */ - public function down() { - $this->message('BlogMigrationTask::down() not implemented'); - } -} diff --git a/code/compat/tasks/MigratableObject.php b/code/compat/tasks/MigratableObject.php deleted file mode 100644 index 59af4ae..0000000 --- a/code/compat/tasks/MigratableObject.php +++ /dev/null @@ -1,8 +0,0 @@ - 'Varchar', - ); - - /** - * @var array - */ - private static $only_available_in = array( - 'none', - ); - - /** - * {@inheritdoc} - */ - public function canCreate($member = null) { - return false; - } - - /** - * {@inheritdoc} - */ - public function up() { - if($this->DisplayMode) { - $this->ArchiveType = 'Monthly'; - - if($this->DisplayMode === 'year') { - $this->ArchiveType = 'Yearly'; - } - } - - $this->ClassName = 'BlogArchiveWidget'; - $this->write(); - return "Migrated " . $this->ArchiveType . " archive widget"; - - } -} diff --git a/code/compat/widgets/TagCloudWidget.php b/code/compat/widgets/TagCloudWidget.php deleted file mode 100644 index 5f7f832..0000000 --- a/code/compat/widgets/TagCloudWidget.php +++ /dev/null @@ -1,44 +0,0 @@ - 'Varchar', - 'Limit' => 'Int', - 'Sortby' => 'Varchar', - ); - - /** - * @var array - */ - private static $only_available_in = array( - 'none', - ); - - /** - * {@inheritdoc} - */ - public function canCreate($member = null) { - return false; - } - - /** - * {@inheritdoc} - */ - public function up() { - $this->ClassName = 'BlogTagsWidget'; - $this->write(); - return "Migrated " . $this->Title . " widget"; - } -} diff --git a/code/tasks/BlogMigrationTask.php b/code/tasks/BlogMigrationTask.php new file mode 100644 index 0000000..15dfcb4 --- /dev/null +++ b/code/tasks/BlogMigrationTask.php @@ -0,0 +1,357 @@ +eol = Director::is_cli() ? PHP_EOL : "
"; + + //PRE-FLIGHT CHECK + // Ensure a dev build has been run by check for some expected tables. + try { + DB::query('SELECT "ID" FROM "Blog"'); + DB::query('SELECT "ID" FROM "BlogPost"'); + echo "Blog and BlogPost tables exist, you are good to migrate" . $this->eol; + } catch (Exception $e) { + echo 'Ensure you have run a dev/build' . $this->eol; + } + + //THE MIGRATION + if($request->getVar('migration') != 1){ + echo $this->eol . 'Ready to run the migration? ' . $this->eol . $this->eol . + 'Run migration only' . $this->eol . $this->eol . + 'Run migration and clean old blog tables' . $this->eol; + exit; + } + + $this->extend('onBeforeBlogMigration',$request, $this->eol); + + //BlogPost Migration + //Migrate BlogEntry to BlogPost include _Live and _versions + try { + DB::query(' + INSERT INTO "BlogPost" ("ID", "PublishDate", "AuthorNames") + ( + SELECT "ID", "Date", "Author" + FROM "BlogEntry" + ) + '); + echo "Migrated BlogEntry to BlogPost" . $this->eol; + } catch (Exception $e) { + echo "BlogEntry to BlogPost migration already run, moving along..." . $this->eol; + } + //BlogPost_Live + try { + DB::query(' + INSERT INTO "BlogPost_Live" ("ID", "PublishDate", "AuthorNames") + ( + SELECT "ID", "Date", "Author" + FROM "BlogEntry_Live" + ) + '); + echo "Migrated BlogEntry_Live to BlogPost_Live" . $this->eol; + } catch (Exception $e) { + echo "BlogEntry_Live to BlogPost_Live migration already run, moving along..." . $this->eol; + } + //BlogPost_version + try { + DB::query(' + INSERT INTO "BlogPost_versions" ("ID", "RecordID", "Version", "PublishDate", "AuthorNames") + ( + SELECT "ID", "RecordID", "Version", "Date", "Author" + FROM "BlogEntry_versions" + ) + '); + echo "Migrated BlogEntry_versions to BlogPost_versions" . $this->eol; + } catch (Exception $e) { + echo "BlogEntry_versions to BlogPost_versions migration already run, moving along..." . $this->eol; + } + //SiteTree ClassName BlogEntry to BlogPost + try { + DB::query('UPDATE "SiteTree" SET "ClassName" = \'BlogPost\' WHERE "ClassName" = \'BlogEntry\''); + DB::query('UPDATE "SiteTree_Live" SET "ClassName" = \'BlogPost\' WHERE "ClassName" = \'BlogEntry\''); + DB::query('UPDATE "SiteTree_versions" SET "ClassName" = \'BlogPost\' WHERE "ClassName" = \'BlogEntry\''); + echo "Updated ClassName reference to BlogPost" . $this->eol; + } catch (Exception $e) { + echo $e; + echo "SiteTree BlogPost ClassName migration already run, moving along..." . $this->eol; + } + + //Migrate BlogHolder to Blog + //Migrate BlogHolder to Blog include _Live and _versions + try { + DB::query(' + INSERT INTO "Blog" ("ID", "PostsPerPage") + ( + SELECT "BlogHolder"."ID", 10 + FROM "BlogHolder" + ) + '); + echo "Migrated BlogHolder to Blog" . $this->eol; + } catch (Exception $e) { + echo "BlogHolder to Blog migration already run, moving along..." . $this->eol; + } + //Blog_Live + try { + DB::query(' + INSERT INTO "Blog_Live" ("ID", "PostsPerPage") + ( + SELECT "BlogHolder_Live"."ID", 10 + FROM "BlogHolder_Live" + ) + '); + echo "Migrated_Live BlogHolder to Blog_Live" . $this->eol; + } catch (Exception $e) { + echo "BlogHolder to Blog migration already run, moving along..." . $this->eol; + } + //Blog_version + try { + DB::query(' + INSERT INTO "Blog_versions" ("ID", "RecordID", "Version", "PostsPerPage") + ( + SELECT "BlogHolder_versions"."ID", "BlogHolder_versions"."RecordID", "BlogHolder_versions"."Version", 10 + FROM "BlogHolder_versions" + ) + '); + echo "Migrated BlogHolder versions to Blog_versions" . $this->eol; + } catch (Exception $e) { + echo "BlogHolder to Blog migration already run, moving along..." . $this->eol; + } + //SiteTree ClassName BlogEntry to BlogPost + try { + DB::query('UPDATE "SiteTree" SET "ClassName" = \'Blog\' WHERE "ClassName" = \'BlogHolder\''); + DB::query('UPDATE "SiteTree_Live" SET "ClassName" = \'Blog\' WHERE "ClassName" = \'BlogHolder\''); + DB::query('UPDATE "SiteTree_versions" SET "ClassName" = \'Blog\' WHERE "ClassName" = \'BlogHolder\''); + echo "Updated ClassName reference to Blog" . $this->eol; + } catch (Exception $e) { + echo $e; + } + + //Migrate BlogTree to Page + try { + DB::query('UPDATE "SiteTree" SET "ClassName" = \'Page\' WHERE "ClassName" = \'SiteTree\''); + DB::query('UPDATE "SiteTree_Live" SET "ClassName" = \'Page\' WHERE "ClassName" = \'SiteTree\''); + DB::query('UPDATE "SiteTree_versions" SET "ClassName" = \'Page\' WHERE "ClassName" = \'SiteTree\''); + echo "Migrated BlogTree to Page" . $this->eol; + } catch (Exception $e) { + echo $e; + } + //Tags migration + try { + $tagcount = $this->migrateTags(); + echo "Migrated " . $tagcount . " tags" . $this->eol; + } catch (Exception $e) { + echo "Error in tag migration (may have already run), moving along..." . $this->eol; + } + + //Legacy Widget migration + if(class_exists('Widget')) { + try { + $this->migrateWidgets(); + } catch (Exception $e) { + echo "Error migrating legacy widgets" . $this->eol; + } + } + + $this->extend('onAfterBlogMigration', $request, $this->eol); + + //IT'S CLEANUP TIME + if($request->getVar('cleanup') == 1){ + try { + $this->cleanUp(); + echo "Cleaned up all old blog tables" . $this->eol; + } catch (Exception $e) { + echo "Error with blog table cleanup (may have already cleaned up), moving along..." . $this->eol; + } + + } + + echo "Migration complete." . $this->eol; + exit; + + } + + /* + * Migrate the tags + * + * @return int number of migrated tags + */ + protected function migrateTags(){ + //1. Get all BlogEntry ID and comma separated tags into an array + $blogtags = DB::query('SELECT ID, Tags FROM BlogEntry_Live')->map('ID','Tags'); + $tagcount = 0; + //2. Foreach split the tags into own array + foreach($blogtags as $blogpostid => $tags){ + foreach($this->tagNames($tags) as $tag) { + //3a. If it's an existing tag, connect the BlogPost and BlogTag as many_many + $existingTagID = DB::query('SELECT ID FROM BlogTag WHERE Title = \'' .$tag. '\'')->value(); + if($existingTagID) { + $tagID = $existingTagID; + } else { + //3b. If it's a new tag, add the BlogTag and then connect the BlogPost and BlogTag as many_many + + //Get the ParentID of the BlogPost + $parentID = DB::query(' + SELECT "ParentID" + FROM "BlogPost_Live" + LEFT JOIN "SiteTree_Live" ON "SiteTree_Live"."ID" = "BlogPost_Live"."ID" + WHERE "BlogPost_Live"."ID" = \'' . $blogpostid . '\'')->value(); + + //Write the new tag using ORM to ensure the URLSegment is generated correctly. + $tagObject = BlogTag::create(); + $tagObject->Title = $tag; + $tagObject->BlogID = $parentID; + $tagObject->write(); + $tagID = $tagObject->ID; + + $tagcount++; + + } + // 4. Add the tag to the blogpost + DB::query(' + INSERT INTO "BlogPost_Tags" + SET + "BlogPostID" = \'' . $blogpostid . '\', + "BlogTagID" = \'' . $tagID . '\'' + ); + + + } + + } + + return $tagcount; + } + + /** + * Safely split and parse all distinct tags assigned to a BlogEntry. + * + * @param string comma-separated tags + * @return array + */ + protected function tagNames($tags) { + $tags = preg_split('/\s*,\s*/', trim($tags)); + + $results = array(); + + foreach($tags as $tag) { + if($tag) $results[mb_strtolower($tag)] = $tag; + } + + return $results; + } + + + /* + * Migrate ArchiveWidget + * + * We set the BlogID to the first Live BlogID that can be found as we cannot know this value from + * the old blog data structure. + * + * Set some default values for the NumberToDisplay as this was also not part of Blog 1.0 data. + */ + protected function migrateWidgets() { + //Get the first Blog ID else set to 0. + $widgetblogid = DB::query('SELECT "ID" FROM "Blog_Live" ORDER BY "ID" LIMIT 1')->value(); + if (!$widgetblogid) { + $widgetblogid = 0; + } + + //ArchiveWidget to BlogArchiveWidget + //Yearly + DB::query(' + INSERT INTO "BlogArchiveWidget" ("ID", "NumberToDispay", "ArchiveType", "BlogID") + ( + SELECT "ID", 10, \'Yearly\', ' . $widgetblogid . ' + FROM "ArchiveWidget" + WHERE "DisplayMode" = \'year\' + ) + '); + + //Monthly + DB::query(' + INSERT INTO "BlogArchiveWidget" ("ID", "NumberToDispay", "ArchiveType", "BlogID") + ( + SELECT "ID", 10, \'Monthly\', ' . $widgetblogid . ' + FROM "ArchiveWidget" + WHERE "DisplayMode" = \'month\' + ) + '); + //Update the Widget ClassName + DB::query('UPDATE "Widget" SET "ClassName" = \'BlogArchiveWidget\' WHERE "ClassName" = \'ArchiveWidget\''); + echo "Migrated ArchiveWidget to BlogArchiveWidget" . $this->eol; + + + // TagCloudWidget to BlogTagsWidget - sort set to Title ASC as no equivalent of 'frequency' exists in blog 2.0 + DB::query(' + INSERT INTO "BlogTagsWidget" ("ID", "Limit", "Order", "Direction", "BlogID") + ( + SELECT "ID", "Limit", \'Title\', \'ASC\', ' . $widgetblogid . ' + FROM "TagCloudWidget" + ) + '); + + //Update the Widget ClassName + DB::query('UPDATE "Widget" SET "ClassName" = \'BlogTagsWidget\' WHERE "ClassName" = \'TagCloudWidget\''); + echo "Migrated TagCloudWidget to BlogTagsWidget" . $this->eol; + } + + /* + * Clean up old tables + * + * @return boolean true of the clean up ran without an issue. + */ + protected function cleanUp() { + DB::query('DROP TABLE "BlogEntry"'); + DB::query('DROP TABLE "BlogEntry_Live"'); + DB::query('DROP TABLE "BlogEntry_versions"'); + DB::query('DROP TABLE "BlogHolder"'); + DB::query('DROP TABLE "BlogHolder_Live"'); + DB::query('DROP TABLE "BlogHolder_versions"'); + DB::query('DROP TABLE "BlogTree"'); + DB::query('DROP TABLE "BlogTree_Live"'); + DB::query('DROP TABLE "BlogTree_versions"'); + DB::query('DROP TABLE "ArchiveWidget"'); + DB::query('DROP TABLE "TagCloudWidget"'); + + $this->extend('updateTablesToCleanUp'); + + return true; + + } +} \ No newline at end of file