2

I am trying to save a SuperTable field that sits within a Matrix field.

I have followed the docs as far as I can but for some reason the SuperTable data is not getting saved.

My steps are as follows:

  1. Get the SuperTable field id:
$matrixBlocks = Craft::$app->getFields()->getFieldByHandle('eventPerformances')->getBlockTypeFields();
$ticketBlockId = $matrixBlocks[2]['id'];
  1. Check that the field has content and loop over it to get the array of data:
if ($event['schedules'][0]['performances'][0]['tickets']) {

    $ticketsMatrix = array();
    $i = 1;

    foreach ($event['schedules'][0]['performances'] as $performance)

    {
        foreach ($performance['tickets'] as $ticket) {
            $ticketsMatrix['new'.$i] = array(
                'type' => $ticketBlockId,
                'enabled' => true,
                'fields' => array(
                    'ticketType' => $ticket['type'],
                    'minPrice' => $ticket['min_price'],
                    'maxPrice' => $ticket['max_price'],
                    'currency' => $ticket['currency'],
                ),
            );
            $i++;
        }
    }
} else {

    $ticketsMatrix = '';
}
  1. Pass this array through when saving the parent Matrix field
$performancesMatrix = array();
$performances = $event['schedules'][0]['performances'];

$i = 1;

foreach ($performances as $performance) {

    $performancesMatrix['new'.$i] = array(
        'type' => 'performance',
        'enabled' => true,
        'fields' => array(
            'performanceDate' => date_create($performance['ts']),
            'duration' => $performance['duration'] / 60,
            'tickets' => $ticketsMatrix
        ),
    );
    $i++;
}

The performanceDate and duration fields get saved as expected but the $ticketsMatrix data is not saving in the nested SuperTable field.

Any assistance would be appreciated!

1 Answer 1

1

Finally figured this out, I had to delve into the matrix field and get the individual block ids for the Supertable fields.

$matrixBlocks = Craft::$app->getFields()->getFieldByHandle('eventPerformances')->getBlockTypeFields();
$ticketBlockId = (int)$matrixBlocks[2]['id'];
$linkBlockId = (int)$matrixBlocks[3]['id'];

$ticketsField = Craft::$app->getFields()->getFieldById($ticketBlockId);
$ticketsBlockTypes = SuperTable::$plugin->getService()->getBlockTypesByFieldId($ticketsField->id);
$ticketsBlockType = $ticketsBlockTypes[0];

$linksField = Craft::$app->getFields()->getFieldById($linkBlockId);
$linkBlockTypes = SuperTable::$plugin->getService()->getBlockTypesByFieldId($linksField->id);
$linksBlockType = $linkBlockTypes[0];

After casting these to integers and then using that value as the type value when saving the matrix block, it all works!

Full code below, hopefully it will help others out in this situation:

$matrixBlocks = Craft::$app->getFields()->getFieldByHandle('eventPerformances')->getBlockTypeFields();
$ticketBlockId = (int)$matrixBlocks[2]['id'];
$linkBlockId = (int)$matrixBlocks[3]['id'];

$ticketsField = Craft::$app->getFields()->getFieldById($ticketBlockId);
$ticketsBlockTypes = SuperTable::$plugin->getService()->getBlockTypesByFieldId($ticketsField->id);
$ticketsBlockType = $ticketsBlockTypes[0];

$linksField = Craft::$app->getFields()->getFieldById($linkBlockId);
$linkBlockTypes = SuperTable::$plugin->getService()->getBlockTypesByFieldId($linksField->id);
$linksBlockType = $linkBlockTypes[0];

$performancesMatrix = array();
$ticketsMatrix = array();
$linksMatrix = array();
$performances = $event['schedules'][0]['performances'];
$i = 1;

foreach ($performances as $performance) {

     if (array_key_exists('tickets', $performance))
     {
         $t = 1;

         foreach ($performance['tickets'] as $ticket) 
         {

             $ticketsMatrix['new'.$t] = array(
                 'type' => $ticketsBlockType->id,
                 'enabled' => true,
                 'fields' => array(
                 'ticketType' => $ticket['type'],
                 'minPrice' => (array_key_exists('min_price', $ticket) ? $ticket['min_price'] : ''),
                 'maxPrice' => (array_key_exists('max_price', $ticket) ? $ticket['max_price'] : ''),
                 'currency' => (array_key_exists('currency', $ticket) ? $ticket['currency'] : ''),
                 ),
             );
             $t++;
         }
     }

    if(array_key_exists('links', $performance))
    {
         $l = 1;
         foreach($performance['links'] as $link) 
         {

             $linksMatrix['new'.$l] = array(
                 'type' => $linksBlockType->id,
                 'enabled' => true,
                 'fields' => array(
                     'linkType' => (array_key_exists('type', $link) ? $link['type'] : ''),
                     'linkUrl' => (array_key_exists('url', $link) ? $link['url'] : ''),
                 ),
             );
             $l++;
         }
     }

     $performancesMatrix['new'.$i] = array(
         'type' => 'performance',
         'enabled' => true,
         'fields' => array(
             'performanceDate' => date_create($performance['ts']),
             'duration' => (array_key_exists('duration', $performance) ? $performance['duration'] / 60 : ''),
             'tickets' => $ticketsMatrix,
              'performanceLinks' => $linksMatrix
         ),
     );
     $i++;
 }

$entry->setFieldValue('eventPerformances', $performancesMatrix);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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