I am writing an importer that pulls from a separate MySQL database into Craft 3, and for the most part it's been quite simple to do.
However, I set myself up for some complication by having a Super Table field inside a Matrix field, which required some acrobatics to retrieve the field information to use when saving the entry.
The code below does work, but I wanted to check if it could be simpler, or if there are any obvious problems with this approach. It could also be helpful to someone else trying to achieve the same thing, as I didn't find anything similar when searching around.
// Get our "quotes" Super Table field (inside "mediaBlocks" matrix field)
if (empty($this->superTableQuotesField)) {
$mediaBlockField = Craft::$app->getFields()->getFieldByHandle('mediaBlocks');
$blockTypes = Craft::$app->getMatrix()->getBlockTypesByFieldId($mediaBlockField->id);
foreach($blockTypes as $blockType) {
if ($blockType->handle=='quotes') {
$matrixFields = Craft::$app->fields->getFieldsByLayoutId($blockType->fieldLayoutId);
// Cache this for future use
$this->superTableQuotesField = SuperTable::$plugin->service->getBlockTypesByFieldId($matrixFields[0]->id);
}
}
}
// For some reason we couldn't find the Super Table field
if (empty($this->superTableQuotesField)) {
Craft::warning('Could not find Super Table field for quotes in mediaBlocks!');
return [];
}
$blockType = $this->superTableQuotesField[0]; // There will only ever be one SuperTable_BlockType
... then a for loop with $q++ on each item from the other db:
$related_quotes['new'.$q] = [
'type' => $blockType->id,
'fields' => [
'quote' => $quote,
'personName' => $personName,
'personCompany' => $personCompany,
]
];
... and then if any found, merge with matrix array:
if (!empty($related_quotes)) {
$i++;
$media_blocks = array_merge(['new'.$i => [
'type' => 'quotes',
'fields' => [
'quotes' => $related_quotes,
]
]], $media_blocks);
}
Is there a better way to do this?
Update:
For comparison, this is the (much simpler) code I'm using to find the $blockType for a Super Table field when it's not an embedded field:
// Get our Super Table field
$field = Craft::$app->getFields()->getFieldByHandle('quotes');
$blockTypes = SuperTable::$plugin->service->getBlockTypesByFieldId($field->id);
$blockType = $blockTypes[0];
... but since this is inside a Matrix field, it doesn't work.
Here's a snapshot of what the field looks like in CP:

$blockTypefor the Super Table field that's inside a Matrix field. It's much easier to just find this info for a base Super Table field (that's not inside a matrix field). I'm guessing there's a simpler way to find that $blockType, but the code block at top was the only way I was successful. – Nate Beaty May 23 '18 at 20:57