14

How can you programmatically save an entry that has a Matrix field in Craft 3?

(Something like this gist for Craft 2)

2 Answers 2

21

Saving Matrix fields programmatically got a lot easier in Craft 3 thanks to all the content refactoring.

use craft\elements\Entry;
use craft\elements\MatrixBlock;

// Figure out the section & entry type
$section = Craft::$app->sections->getSectionByHandle('news');
$entryTypes = $section->getEntryTypes();
$entryType = reset($entryTypes);

// Create an entry
$entry = new Entry([
    'sectionId' => $section->id,
    'typeId' => $entryType->id,
    'fieldLayoutId' => $entryType->fieldLayoutId,
    'authorId' => 1,
    'title' => 'My Entry',
    'slug' => 'my-entry',
    'postDate' => new DateTime(),
]);

// Set the custom field values (including Matrix)
$entry->setFieldValues([
    'summary' => 'Some "summary" custom field value...',
    'matrixField' => [
        'new1' => [
            'type' => 'blockTypeHandle',
            'fields' => [
                // the block's custom field values...
            ],
        ],
        'new2' => [
            'type' => 'blockTypeHandle',
            'fields' => [
                // the block's custom field values...
            ],
        ],
    ],
]);

// Save the entry
Craft::$app->elements->saveElement($entry);
11

Just an additional note:

If you want to append certain elements to your matrix field instead of overwriting them all you have to do

/** @var \craft\fields\Matrix $field */
$field = Craft::$app->getFields()->getFieldByHandle('matrixField');

// get the existing matrixField Value, keep in mind, this is a Query and not an array
$existingMatrixQuery = $element->getFieldValue('matrixField');

// serialize the data in order to get an array like Brandon Kelly
// created in his answer
$serializedMatrix = $field->serializeValue($existingMatrixQuery, $element);

// append the new blocks to the existing array
$serializedMatrix['new1'] = [
    'type' => 'blockTypeHandle',
    'fields' => [
        // the block's custom field values...
    ]
];

$element->setFieldValue('matrixField', $serializedMatrix);

// Save the entry
Craft::$app->elements->saveElement($element);
1
  • This is perfect, thanks Robin! It's icing on the cake that Brandon has baked. :)
    – Lindsey D
    Sep 1, 2019 at 5:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.