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?

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);
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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