2

I've written a plugin to update some user profile fields via ajax. It works great for normal text fields like this 'myWooly' field, ex:

<?php
namespace Craft;

class ProfileUpdateController extends BaseController
{
    protected $allowAnonymous = true;

    /**
     * updateWooly
     */
    public function actionUpdateWooly()
    {
        $this->requireAjaxRequest();

        $post = craft()->request->getPost();

        // get current user's profile info
        $currentUser = craft()->userSession->getUser();
        $profile = $currentUser->getContent();

        $currentUser->getContent()->myWooly = $post['myWooly'];

        if (craft()->users->saveUser($currentUser)) {
            $response = 'success';
        }
        else {
            $response = 'error';
        }

        $this->returnJson($response);
    }

I've created a Matrix field with each block having its own Wooly, ex:

Kids (Matrix field)
 - kid (block type)
  + firstName
  + wooly
 - kid
  + firstName
  + wooly
 - etc. 

...and now I need for users to update the 'wooly' within each Matrix block.

I've updated my AJAX call to POST a Matrix Block ID and updated my actionUpdateWooly() action to the following:

    public function actionUpdateWooly()
    {
        $this->requireAjaxRequest();

        $post = craft()->request->getPost();

        // get current user's profile info
        $currentUser = craft()->userSession->getUser();
        $profile = $currentUser->getContent();

        // SAVE WOOLY IN KIDS MATRIX FIELD
        if (isset($post['kidId'])) {

            $kidsMatrix = craft()->fields->getFieldByHandle("kids");

            $kidsMatrixBlocks = craft()->matrix->getBlockTypesByFieldId($kidsMatrix->id);
            foreach ($kidsMatrixBlocks as $key => $data) {
                if ($data->handle === "kid") {
                    $kidBlock = $data;
                    break;
                };
            };

            $block = new MatrixBlockModel($post['kidId']);
            $block->fieldId    = $kidsMatrix->id; // Matrix field's ID, 'Kids'
            $block->ownerId    = $currentUser->id; // ID of entry the block should be added to
            $block->typeId     = $kidBlock->id; // ID of block type, 'kid'
            $block->getContent()->setAttributes(array(
                'wooly' => $post['myWooly'],
            ));

            $response = craft()->matrix->saveBlock($block);

        }

        // WOOLY STORED AT TOP-LEVEL OF ACCOUNT
        else {
            $currentUser->getContent()->myWooly = $post['myWooly'];
        }

        if (craft()->users->saveUser($currentUser)) {
            $response = 'success';
        }
        else {
            $response = 'error';
        }

        $this->returnJson($response);
    }

This is successfully CREATING NEW matrix blocks in the correct field, but it's not UPDATING the one I'm expecting.

I would expect this to get the Matrix block by ID but apparently it's not:

$block = new MatrixBlockModel($post['kidId']);

Yes, I've made sure the Matrix Block ID

Can anybody spot what I should be doing differently to get a specific matrix block and updated it within a user profile?

1 Answers1

2

I believe this is the correct way to get an existing Matrix block. Found this gem after digging around in the Google group.

$block = craft()->matrix->getBlockById(blockId);

I updated my plugin code above to this and it seems to work properly.

// THIS DOESN'T WORK
// $block = new MatrixBlockModel($post['kidId']);

// THIS WORKS
$block = craft()->matrix->getBlockById($post['kidId']);

$block->fieldId    = $kidsMatrix->id; // Matrix field's ID, 'Kids'
$block->ownerId    = $currentUser->id; // ID of entry the block should be added to
$block->typeId     = $kidBlock->id; // ID of block type, 'kid'
$block->getContent()->setAttributes(array(
    'wooly' => $post['myWooly'],
));

$response = craft()->matrix->saveBlock($block);