1

Is there a "Craft" way of handling this in 3.1?

Solutions to this question on SE are based on older versions of Craft which no longer work.

Custom fields can be duplicated by doing:

$newEntry->customFieldHandle = $masterEntry->customFieldHandle;

I've tested this with Plain Text, Number, Dropdown, Date/Time, Entries fields and it works fine.

I tried this with a matrix field (not expecting it to work, as I appreciate Matrix fields are handled differently). The matrix content and fields are copied across when a newEntry is generated, but is deleted from the masterEntry.

Example module:

protected static function createNewEntry()
{
    Event::on(
        Elements::class,
        Elements::EVENT_AFTER_SAVE_ELEMENT,
        function(ElementEvent $event) {

            // Ignore any element that is not an entry
            if (!($event->element instanceof Entry)) {
                return;
            }

            // Ignore entries that are new because they have no id
            if ($event->isNew) {
                return;
            }

            // Fetch current entry and assign siteid
            $masterEntry = Craft::$app->entries->getEntryById($event->element->id, $event->element->siteId);

            // Basic Craft fields...
            $newEntry = new Entry();
            $newEntry->sectionId = $masterEntry->sectionId;
            // more craft fields here...

            // Custom fields 
            $newEntry->contentLongtitle = $masterEntry->contentLongtitle;
            // more craft custom fields here...

            // Matrix field 
            // Doing this copies the matrix content to newEntry
            // but deletes it from masterEntry
            $newEntry->matrixSchedule = $masterEntry->matrixSchedule;

            $success = Craft::$app->elements->saveElement($newEntry);
            // Handle success/failure logic here...

        }
    );
}
Warmbeat
  • 81
  • 5

1 Answers1

2

I've just found this: https://craftcms.stackexchange.com/a/25961/9344.

After reading Robins comments, I can see where I was going wrong.

My working example code now looks like this:

protected static function createNewEntry()
{
    Event::on(
        Elements::class,
        Elements::EVENT_AFTER_SAVE_ELEMENT,
        function(ElementEvent $event) {

            // Ignore any element that is not an entry
            if (!($event->element instanceof Entry)) {
                return;
            }

            // Ignore entries that are new because they have no id
            if ($event->isNew) {
                return;
            }

            // Fetch current entry and assign siteid
            $masterEntry = Craft::$app->entries->getEntryById($event->element->id, $event->element->siteId);

            // Fetch matrix fields by handle
            $masterEntryMatrix = Craft::$app->getFields()->getFieldByHandle('matrixSchedule');
            // get the existing matrixSchedule value
            $masterEntryMatrixQuery = $masterEntry->getFieldValue('matrixSchedule');
            // serialize the data in order to get an array
            $masterEntryMatrixSerialized = $masterEntryMatrix->serializeValue($masterEntryMatrixQuery, $masterEntry);

            // Basic Craft fields...
            $newEntry = new Entry();
            $newEntry->sectionId = $masterEntry->sectionId;
            // more craft fields here...

            // Custom fields 
            $newEntry->contentLongtitle = $masterEntry->contentLongtitle;
            // more craft custom fields here...

            // Matrix field 
            $newEntry->setFieldValue('matrixSchedule', $masterEntryMatrixSerialized);

            $success = Craft::$app->elements->saveElement($newEntry);
            // Handle success/failure logic here...

        }
    );
}
Warmbeat
  • 81
  • 5