1

When I import using JSON with FeedMe Pro and need to import more records into an entry that has a Matrix field. I find it deletes the previous and adds the new data only. Is there anyway to append to the Matrix field leaving the previous data intact?

Vin
  • 383
  • 3
  • 15

1 Answers1

1

In addition to How to save Matrix data programmatically in Craft 3

You'll fetch your data loop each row and fetch the element / create a new element if none exists

$section = Craft::$app->sections->getSectionByHandle('news');
$entryTypes = $section->getEntryTypes();
$entryType = reset($entryTypes);
foreach ($jsonData as $row) {
    // try to fetch an element
    $element = Craft::$app->getElements()->getElementById($row['id']);
    // no element exists, create a new one
    if ($element === null) {
        $element = new Entry(
            [
                'sectionId'     => $section->id,
                'typeId'        => $entryType->id,
                'fieldLayoutId' => $entryType->fieldLayoutId,
                'authorId'      => 1,
                'title'         => 'My Entry',
                'slug'          => 'my-entry',
                'postDate'      => new DateTime(),
            ]
        );
    }
    // get the field by handle
    /** @var \craft\fields\Matrix $field */
    $field = Craft::$app->getFields()->getFieldByHandle('matrix');

    // get the existing matrix blocks
    $existingMatrix = $element->getFieldValue('matrix');

    // serialize the data
    $serializedMatrix = $field->serializeValue($existingMatrix, $element);

   // loop your json matrix blocks
    foreach ($row['yourMatrixBlocks'] as $key => $block) {
        // append your new Matrix fields
        $serializedMatrix['new' . $key] = [
            'type'   => 'block',
            'fields' => [
                'field' => $block['field']
            ],
        ];
    }

    // set the new field value
    $element->setFieldValue('matrix', $serializedMatrix);
    $success = Craft::$app->getElements()->saveElement($element);

    // display errors - just in Case
    if($success === false){
        Craft::dd($element->getErrors());    
    }
}
Robin Schambach
  • 19,713
  • 1
  • 19
  • 44
  • Excellent! I was hoping it was not beyond me, I am so far away from being a dev, I am a digital marketer filling in to get this working. My Matrix field has a Table field in it too. I have to see what I can do with it, but thank you! – Vin May 02 '18 at 08:22
  • The easiest way to get the data structure for the required field type is to take a look at your $_POST variable when you save an element in your CP. – Robin Schambach May 02 '18 at 08:27
  • Makes sense, I have current entries I need to update so gotta see with spending some time taking a go at it. – Vin May 02 '18 at 08:32
  • I have around 10,000 records to import in, so thinking this may be a solution best suited for FeedMe if I can get it to work. – Vin May 02 '18 at 08:52
  • You can change the code in FeedMe as well if you want – Robin Schambach May 02 '18 at 08:56
  • I was thinking to do that or at least try, but not sure why the current Matrix entries would be deleted when new entries to that field are added. Doesn't make sense. – Vin May 02 '18 at 09:08
  • It does, because you overwrite the field value.. When you insert a new title for an entry you'll overwrite it. It does not make any sense to attach the new string to the old one – Robin Schambach May 02 '18 at 09:36
  • I am trying to simple update the current entry with new data into that Mateix field, create more rows and leave the old ones be. So to me in my non-dev thinking it should always append. – Vin May 02 '18 at 09:51
  • This does not make sense because you won't ever be able to delete blocks this way. How are you going to remove matrix blocks? Your non-dev thinking is not really accurate – Robin Schambach May 02 '18 at 11:24
  • Yes it is accurate to me, your dev thinking is wrong to me, haha. I say you can go into the entry and delete the blocks and add, but importing should append only. – Vin May 02 '18 at 17:58
  • Personally, both methods are valid, and there should be an option for how to handle this. The massive issue here, it what happens if you import a feed multiple times? You'll always be appending blocks to the Matrix field. But, it is the current expected behaviour to overwrite the contents of Matrix fields on import - just like it does with every other field. – crawf May 04 '18 at 13:49