<p>If you only need to update a field value in an existing matrix block, not add new ones or remove existing ones, you don't need the user at all. Matrix blocks are elements themselves, so you can save them independently from their owner element.</p>
<p>Since you already have the ID of the matrix block, you can use a <a href="https://craftcms.com/docs/4.x/matrix-fields.html#querying-elements-with-matrix-fields" rel="nofollow noreferrer">matrix block query</a> to find that block:</p>
<pre class="lang-php prettyprint-override"><code>use craft\elements\MatrixBlock;

$blockId = 123;
$matrixBlock = MatrixBlock::find()
    -&gt;id($blockId)
    -&gt;one();
</code></pre>
<p>Then you can modify the field values on that matrix block and save it using the <a href="https://docs.craftcms.com/api/v4/craft-services-elements.html" rel="nofollow noreferrer"><code>Elements</code> service</a>:</p>
<pre class="lang-php prettyprint-override"><code>use Craft;

$matrixBlock-&gt;setFieldValues([
    'body' =&gt; 'Foo',
    'my_field' =&gt; 'Bar', 
]);
$success = Craft::$app-&gt;getElements()-&gt;saveElement($matrixBlock);
if (!$success) {
    // Catch validation errors
}
</code></pre>
<p>If you also need to add or remove blocks, you'll need the <code>User</code> element as well, you can always find that through <code>$matrixBlock-&gt;owner</code>. The <a href="https://craftcms.com/docs/4.x/matrix-fields.html#saving-matrix-fields" rel="nofollow noreferrer">documentation on saving matrix fields</a> has examples for adding new blocks and updating existing ones.</p>

CC BY-SA 4.0
2023-04-17T07:59:10.730Z
2023-04-17T07:59:10.730Z
MoritzLost
<p>Appreciate I may be asking for a lot here - I have an existing module that I use to fire events when a stripe order is completed.</p>
<p>I would like to iterate through some User matrix blocks and update a dropdown field value (I have the IDs of the blocks from the stripe order)</p>
<p>This is far as I have got I'm afraid.. happy to look at some docs or be pointed in the right direction. I have other code in the module that does similar to entries, i just cannot work out how to find the matrix blocks by user + ID, and then update the dropdown field.</p>
<p>thanks</p>
<pre><code>Event::on(Orders::class, Orders::EVENT_AFTER_ORDER_COMPLETE, function(OrderCompleteEvent $e) {
            
            // get the order
            $order = $e-&gt;order;
            
            //get the fields from the order
            $fields= $order-&gt;getFormFields();
            

            // TROPHY ORDERS
            if (!empty($fields['Trophies'])) {
                
                //create array of ids from Trophies field in the order
                $blockIds = explode(',', $fields['Trophies']);

             // Get the user from the order
            $user = Craft::$app-&gt;getUsers()-&gt;getUserByUsernameOrEmail($order-&gt;email);
                
                ///do something here to find matrix blocks with the above ID's and then update a dropdown in each one to &quot;paid&quot;
                
                // save
                return Craft::$app-&gt;getElements()-&gt;saveElement($user, false);
                
            }           
             
         });
</code></pre>

<craft3><matrix><users><modules>
Update user matrix field dropdown through module
# Update user matrix field dropdown through module

(Asked by: username_0 on 2023-04-14)

Appreciate I may be asking for a lot here - I have an existing module that I use to fire events when a stripe order is completed.
I would like to iterate through some User matrix blocks and update a dropdown field value (I have the IDs of the blocks from the stripe order)
This is far as I have got I'm afraid.. happy to look at some docs or be pointed in the right direction. I have other code in the module that does similar to entries, i just cannot work out how to find the matrix blocks by user + ID, and then update the dropdown field.
thanks
Event::on(Orders::class, Orders::EVENT_AFTER_ORDER_COMPLETE, function(OrderCompleteEvent $e) {
            
            // get the order
            $order = $e->order;
            
            //get the fields from the order
            $fields= $order->getFormFields();
            

            // TROPHY ORDERS
            if (!empty($fields['Trophies'])) {
                
                //create array of ids from Trophies field in the order
                $blockIds = explode(',', $fields['Trophies']);

             // Get the user from the order
            $user = Craft::$app->getUsers()->getUserByUsernameOrEmail($order->email);
                
                ///do something here to find matrix blocks with the above ID's and then update a dropdown in each one to "paid"
                
                // save
                return Craft::$app->getElements()->saveElement($user, false);
                
            }           
             
         });

**Tags:** craft3, matrix, users, modules


---

## 1 answers

### Answer by username_1 on 2023-04-17. Score: 1 | Accepted answer

If you only need to update a field value in an existing matrix block, not add new ones or remove existing ones, you don't need the user at all. Matrix blocks are elements themselves, so you can save them independently from their owner element.
Since you already have the ID of the matrix block, you can use a matrix block query to find that block:
use craft\elements\MatrixBlock;

$blockId = 123;
$matrixBlock = MatrixBlock::find()
    ->id($blockId)
    ->one();

Then you can modify the field values on that matrix block and save it using the Elements service:
use Craft;

$matrixBlock->setFieldValues([
    'body' => 'Foo',
    'my_field' => 'Bar', 
]);
$success = Craft::$app->getElements()->saveElement($matrixBlock);
if (!$success) {
    // Catch validation errors
}

If you also need to add or remove blocks, you'll need the User element as well, you can always find that through $matrixBlock->owner. The documentation on saving matrix fields has examples for adding new blocks and updating existing ones.


---

