I'm going to look pretty dumb if somebody drops a one-line answer down the line, but here goes: AFAIK, unfortunately, "cloning" an element (e.g. an EntryModel) isn't that simple.
For one, $model->getContent()
will pull the entry's ContentModel, which basically contains all the custom fields that are stored in the craft_content
table for your particular entry. Unfortunately, certain fieldtypes (e.g. Matrix, relational fields such as Assets, Categories, Entries etc) don't actually store their content in the craft_content
table, so their values in the ContentModel will be null
. To get to those values, you'll basically have to loop over your original entry's FieldLayout, and pull each field's actual value. You could then apply those values to your new EntryModel's setContentFromPost()
method, but remember that relational fields (such as Assets and Entries) should be set as an array of IDs, not an ElementCriteriaModel (which is what you'll get back when you pull the field using $entry->$someFieldHandle
or $entry->getFieldValue('someFieldHandle')
.
If the entry you want to clone has Matrix fields, that's another can of worms. Matrix blocks are actually elements in themselves, and you'll basically need to follow the same pattern as with cloning the entry itself, in order to properly "clone" the blocks.
Unfortunately, I don't have a full, working example typed out, but here's some non-tested boilerplate code to get you started (I conveniently skipped the Matrix part, but there's a link at the bottom which may be helpful):
$newModel = $model->copy();
$newModel->id = null;
// Loop through the original model's custom field values, and set them to the new model; account for relational fields
$customFieldValues = [];
foreach ($model->getFieldLayout()->getFields() as $fieldLayoutField) {
$field = $fieldLayoutField->getField();
$fieldType = $field->type;
$fieldHandle = $field->handle;
$fieldValue = null;
switch ($fieldType) {
case 'Assets': case 'Entries': case 'Categories': case 'Tags': case 'Users':
$fieldValue = $model->$fieldHandle->ids();
break;
case 'Matrix':
// Whoa, Nelly
break;
default:
$fieldValue = $model->$fieldHandle;
}
if ($fieldValue) {
$customFieldValues[$fieldHandle] = $fieldValue;
}
}
$newModel->setContentFromPost($customFieldValues);
// Save the new entry
$success = craft()->entries->saveEntry($newModel);
Note that if you need this to work for all element types, you may get away with calling craft()->elements->saveElement($newModel)
at the end, instead of the EntriesService::saveEntry
method. Otherwise, you'll need to check the $newModel->elementType
property, and call the appropriate service's method for saving the element.
Finally, here are some other SE threads that may be of interest:
Getting all content, including Matrix fields from an EntryModel
How to get all (prepped) field values from an entry, indexed by field handle
Duplicating Matrix fields with content from another locale