Last active
February 1, 2016 14:07
-
-
Save joshangell/26d6413a1eb243d4e8a1 to your computer and use it in GitHub Desktop.
Revisions
-
joshangell renamed this gist
Jan 22, 2016 . 1 changed file with 4 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -9,15 +9,13 @@ class MyPluginController extends BaseController /** * Start the migration Task */ public function actionMigrate() { // Create the Task craft()->tasks->createTask('MyPlugin_MigrateManager'); if (!craft()->tasks->isTaskRunning()) { // Is there a pending task? $task = craft()->tasks->getNextPendingTask(); @@ -31,6 +29,6 @@ public function actionMigrate() craft()->tasks->runPendingTasks(); } } } } -
joshangell revised this gist
Jan 22, 2016 . 3 changed files with 57 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -29,7 +29,7 @@ public function getTotalSteps() $criteria->enabled = null; $criteria->limit = null; $criteria->status = null; $criteria->sectionId = 15; // The ID of the section we are copying from $elements = $criteria->find(); // Chunk the elements into groups of 10 - if the content is quite This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -48,18 +48,18 @@ public function runStep($step) $criteria->enabled = null; $criteria->limit = null; $criteria->status = null; $criteria->sectionId = 22; // The ID of the section we are copying to $criteria->title = $element->getContent()->title; $targetElement = $criteria->first(); // If we didn’t get an existing element, make one here if (!$targetElement) { $targetElement = new EntryModel(); $targetElement->sectionId = 22; $targetElement->typeId = 23; // The ID of the Entry Type we want } // NOTE: This is where it gets fun - copy your field content! // Copy the blocks from a Matrix field - be aware that if the target // element already exists and has blocks they will be lost. @@ -71,7 +71,7 @@ public function runStep($step) { // Setup a new block $newBlock = new MatrixBlockModel(); $newBlock->fieldId = 4; // Whatever the ID of `myMatrixField` is $newBlock->typeId = $block->getType()->id; $newBlock->ownerId = $targetElement->id; $newBlock->locale = $block->locale; @@ -90,6 +90,7 @@ public function runStep($step) if (in_array($field->type, array('Assets', 'Entries', 'Categories', 'Tags'))) { $value = $block->$fieldHandle->ids(); } else { // For ‘normal’ fields just copy their content directly $value = $block->$fieldHandle; } @@ -105,16 +106,30 @@ public function runStep($step) // Set the content on the target element $targetElement->setContent(array( // Don’t forget a title! 'title' => $element->getContent()->title, // Here are the Matrix blocks we just made 'myMatrixField' => $newBlocks, // Same as inside the Matrix, just get the IDs of relationship fields 'someAssetField' => $element->someAssetField->ids(), // Simpler fields can just be directly copied 'someSimpleTextField' => $element->someSimpleTextField, )); // Keep a bunch of attributes $targetElement->setAttributes(array( 'slug' => $sourceElement->slug, 'postDate' => $sourceElement->postDate, 'expiryDate' => $sourceElement->expiryDate, 'enabled' => $sourceElement->enabled, 'archived' => $sourceElement->archived, 'localeEnabled' => $sourceElement->localeEnabled, )); // Wrap in a transaction in case something goes wrong $transaction = craft()->db->getCurrentTransaction() === null ? craft()->db->beginTransaction() : null; try { This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,36 @@ <?php namespace Craft; class MyPluginController extends BaseController { // This lets anyone run the controller actions we specify, useful for CRON etc protected $allowAnonymous = array('actionMigrate'); /** * Start the migration Task */ public function actionMigrate() { // Create the Task craft()->tasks->createTask('MyPlugin_MigrateManager'); if (!craft()->tasks->isTaskRunning()) { // Is there a pending task? $task = craft()->tasks->getNextPendingTask(); if ($task) { // Attempt to close the connection if this is an Ajax request if (craft()->request->isAjaxRequest()) { craft()->request->close(); } // Start running tasks craft()->tasks->runPendingTasks(); } } } } -
joshangell created this gist
Jan 18, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,62 @@ <?php namespace Craft; class MyPlugin_MigrateManagerTask extends BaseTask { private $_elements; /** * @inheritDoc ITask::getDescription() * * @return string */ public function getDescription() { return Craft::t('Migrating old content'); } /** * @inheritDoc ITask::getTotalSteps() * * @return int */ public function getTotalSteps() { // Setup the criteria for finding the elements we want to migrate $criteria = craft()->elements->getCriteria(ElementType::Entry); $criteria->enabled = null; $criteria->limit = null; $criteria->status = null; $criteria->sectionId = 15; $elements = $criteria->find(); // Chunk the elements into groups of 10 - if the content is quite // light you may want to up this to 100 or so $this->_elements = array_chunk($elements, 10); return count($this->_elements); } /** * @inheritDoc ITask::runStep() * * @param int $step * * @return bool */ public function runStep($step) { // I frequently found I ran out of memory doing these sort of operations // so just bumped up what Craft is allowed to use here - in this to 2.5GB craft()->config->set('phpMaxMemoryLimit', '2560M'); craft()->config->maxPowerCaptain(); // Run the migration as a sub Task with the current chunk of elements return $this->runSubTask('MyPlugin_Migrate', null, array( 'elements' => $this->_elements[$step] )); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,171 @@ <?php namespace Craft; class MyPlugin_MigrateTask extends BaseTask { /** * @inheritDoc ITask::getDescription() * * @return string */ public function getDescription() { return Craft::t('Migrating ...'); } /** * @inheritDoc ITask::getTotalSteps() * * @return int */ public function getTotalSteps() { return count($this->getSettings()->elements); } /** * @inheritDoc ITask::runStep() * * @param int $step * * @return bool */ public function runStep($step) { // Again, bump the memory craft()->config->set('phpMaxMemoryLimit', '2560M'); craft()->config->maxPowerCaptain(); // Get the element we want to copy from $element = $this->getSettings()->elements[$step]; // See if the one we are copying to already exists. // What you use to determine this will vary, in this case I just // used the title but you may need something more bullet proof. $criteria = craft()->elements->getCriteria(ElementType::Entry); $criteria->enabled = null; $criteria->limit = null; $criteria->status = null; $criteria->sectionId = 22; $criteria->title = $element->getContent()->title; $targetElement = $criteria->first(); // If we didn’t get an existing element, make one here if (!$targetElement) { $targetElement = new EntryModel(); $targetElement->sectionId = 22; $targetElement->typeId = 23; } // XXX This is where it gets fun - copy your field content! // Copy the blocks from a Matrix field - be aware that if the target // element already exists and has blocks they will be lost. // ref: https://craftcms.stackexchange.com/questions/8517/duplicating-matrix-fields-with-content-from-another-locale $newBlocks = array(); $i = 0; foreach ($element->myMatrixField->find() as $block) { // Setup a new block $newBlock = new MatrixBlockModel(); $newBlock->fieldId = 4; $newBlock->typeId = $block->getType()->id; $newBlock->ownerId = $targetElement->id; $newBlock->locale = $block->locale; $newBlockContent = $newBlock->getContent(); $values = array(); // Loop the fields on this block foreach ($block->getFieldLayout()->getFields() as $blockFieldLayoutField) { $field = $blockFieldLayoutField->getField(); $fieldHandle = $field->handle; // Cope with element fields by getting an array of their IDs if (in_array($field->type, array('Assets', 'Entries', 'Categories', 'Tags'))) { $value = $block->$fieldHandle->ids(); } else { $value = $block->$fieldHandle; } $values[$fieldHandle] = $value; } // Set the content on the new block $newBlock->setContentFromPost($values); $newBlocks['new'.$i] = $newBlock; $i++; } // Set the content on the target element $targetElement->setContent(array( 'title' => $element->getContent()->title, 'myMatrixField' => $newBlocks, // Same as before, just get the IDs of relationship fields 'someAssetField' => $element->someAssetField->ids(), // Simpler fields can just be directly copied 'someSimpleTextField' => $element->someSimpleTextField, )); // Wrap in a transaction in case something goes wrong $transaction = craft()->db->getCurrentTransaction() === null ? craft()->db->beginTransaction() : null; try { // Try and save, throw an exception if it didn’t for some reason if (!craft()->entries->saveEntry($targetElement)) { // Try and get the errors so the log is more useful if ($targetElement->hasErrors()) { $firstError = array_shift($targetElement->getErrors())[0]; throw new Exception(Craft::t('Couldn’t migrate from {title}. First error to correct: {error}', array('title' => $element->title, 'error' => firstError))); } else { throw new Exception(Craft::t('Couldn’t migrate from {title}.', array('title' => $element->title))); } } if ($transaction !== null) { $transaction->commit(); } } catch (Exception $e) { if ($transaction !== null) { $transaction->rollback(); } // Log that exception message so we can debug it in the log viewer MyPlugin::log($e->getMessage(), LogLevel::Error); return $e->getMessage(); } return true; } /** * @inheritDoc BaseSavableComponentType::defineSettings() * * @return array */ protected function defineSettings() { return array( 'elements' => AttributeType::Mixed ); } }