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