<p>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.</p>

<p>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.</p>

<p>The code below <em>does</em> 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.</p>

<pre><code>// Get our "quotes" Super Table field (inside "mediaBlocks" matrix field)
if (empty($this-&gt;superTableQuotesField)) {
    $mediaBlockField = Craft::$app-&gt;getFields()-&gt;getFieldByHandle('mediaBlocks');
    $blockTypes = Craft::$app-&gt;getMatrix()-&gt;getBlockTypesByFieldId($mediaBlockField-&gt;id);
    foreach($blockTypes as $blockType) {
        if ($blockType-&gt;handle=='quotes') {
            $matrixFields = Craft::$app-&gt;fields-&gt;getFieldsByLayoutId($blockType-&gt;fieldLayoutId);
            // Cache this for future use
            $this-&gt;superTableQuotesField = SuperTable::$plugin-&gt;service-&gt;getBlockTypesByFieldId($matrixFields[0]-&gt;id);
        }
    }
}
// For some reason we couldn't find the Super Table field
if (empty($this-&gt;superTableQuotesField)) {
    Craft::warning('Could not find Super Table field for quotes in mediaBlocks!');
    return [];
}

$blockType = $this-&gt;superTableQuotesField[0]; // There will only ever be one SuperTable_BlockType
</code></pre>

<p>... then a for loop with <code>$q++</code> on each item from the other db:</p>

<pre><code>$related_quotes['new'.$q] = [
    'type' =&gt; $blockType-&gt;id,
    'fields' =&gt; [
        'quote'         =&gt; $quote,
        'personName'    =&gt; $personName,
        'personCompany' =&gt; $personCompany,
    ]
];
</code></pre>

<p>... and then if any found, merge with matrix array:</p>

<pre><code>if (!empty($related_quotes)) {
    $i++;
    $media_blocks = array_merge(['new'.$i =&gt; [
        'type' =&gt; 'quotes',
        'fields' =&gt; [
            'quotes' =&gt; $related_quotes,
        ]
    ]], $media_blocks);
}
</code></pre>

<p>Is there a better way to do this? </p>

<p><strong>Update:</strong> </p>

<p>For comparison, this is the (much simpler) code I'm using to find the <code>$blockType</code> for a Super Table field when it's not an embedded field:</p>

<pre><code>// Get our Super Table field
$field = Craft::$app-&gt;getFields()-&gt;getFieldByHandle('quotes');
$blockTypes = SuperTable::$plugin-&gt;service-&gt;getBlockTypesByFieldId($field-&gt;id);
$blockType = $blockTypes[0];
</code></pre>

<p>... but since this is inside a Matrix field, it doesn't work. </p>

<p>Here's a snapshot of what the field looks like in CP:</p>

<p><a href="https://i.sstatic.net/LzT4a.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/LzT4a.png" alt="quotes super table field in mediaBlock matrix field"></a></p>

CC BY-SA 4.0
2018-05-23T20:09:37.903Z
Could you maybe explain the first code snipped? I don't really see why this is important or what it should be good for. You could use this as reference. It's without a super table field but they work similar https://craftcms.stackexchange.com/questions/21864/how-to-save-matrix-data-programmatically-in-craft-3
Robin Schambach
CC BY-SA 4.0
2018-05-23T20:57:52.063Z
Sure, it is pretty confusing. I'm trying to find the `$blockType` for 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
CC BY-SA 4.0
2018-05-23T21:20:41.390Z
Are you going to change/delete your fields because that's what calling by handle is good for. You can as well grab the field by id directly. It's not as dynamic as your approach but yours won't work anymore when you change the layout as well
Robin Schambach
CC BY-SA 4.0
2018-05-24T20:39:41.480Z
There aren't any plans to change fields, and I did initially just use the field ID by checking the database directly. I sent this issue to the Super Table devs also in case they wanted to chime in — I was just wondering if there was a more elegant way to find a Super Table's field info from inside a matrix field.
Nate Beaty
<craft3><plugin-supertable>
Finding Super Table field in matrix field
# Finding Super Table field in matrix field

(Asked by: username_0 on 2018-05-23)

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:

**Tags:** craft3, plugin-supertable
> **Comments:**
> **username_1**: Could you maybe explain the first code snipped? I don't really see why this is important or what it should be good for. You could use this as reference. It's without a super table field but they work similar https://craftcms.stackexchange.com/questions/21864/how-to-save-matrix-data-programmatically-in-craft-3  
> **username_0**: Sure, it is pretty confusing. I'm trying to find the `$blockType` for 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.  
> **username_1**: Are you going to change/delete your fields because that's what calling by handle is good for. You can as well grab the field by id directly. It's not as dynamic as your approach but yours won't work anymore when you change the layout as well  
> **username_0**: There aren't any plans to change fields, and I did initially just use the field ID by checking the database directly. I sent this issue to the Super Table devs also in case they wanted to chime in — I was just wondering if there was a more elegant way to find a Super Table's field info from inside a matrix field.  

---

## 0 answers

