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; // 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. // 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; // Whatever the ID of `myMatrixField` is $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 { // For ‘normal’ fields just copy their content directly $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( // 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 { // 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 ); } }