Magento – Copy a Widget Instance Programmatically, Preserving Layout Updates

debuggingwidgets

I try to copy a widget instance.

The following function is run from a console script (shell/), adminhtml Events are initialized.

The problem: What I get from the $orig->getData('page_groups') differs from the array format Magento uses when submitting the backend edit page for a widget instance (CMS -> Instances).

I will post an answer, but I am happy if somebody finds a better solution.

Best Answer

/**
 * Copy widget instance
 *
 * @param $id
 * @return int id of the duplicate
 */
public function copyWidgetInstance($id)
{
    $orig = Mage::getModel('widget/widget_instance')->load($id);

    $data = $orig->getData();
    unset($data['instance_id']);
    $data['store_ids'] = $this->getDestination()->getId();
    $data['title'] = $this->getPrefix() . $data['title'] . date('H-i-s');

    /**
     * rebuild page group, to pass the isset($pageGroup[$pageGroup['page_group']])
     * @see Mage_Widget_Model_Widget_Instance::_beforeSave
     */

    $new_page_groups = array();
    foreach($data['page_groups'] as $group) {
        $page_group_name = $group['page_group']; // i.e. 'anchor_categories', 'simple_products'
        $new_group = array(
            'page_group' => $page_group_name,
             $page_group_name => array(
                 'page_id' => $group['page_id'],
                 'layout_handle' => $group['layout_handle'],
                 'entities' => $group['entities'],
                 'for' => $group['page_for'],
                 'block' => $group['block_reference'],
                 'template' => $group['page_template'],
             )
        );
        $new_page_groups[] = $new_group;
    }

    $data['page_groups'] = $new_page_groups;


    // copy
    $duplicate = Mage::getModel('widget/widget_instance');
    $duplicate->setData($data);
    $duplicate->save();

    return $duplicate->getId();
}