1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

How to use the datawriter to write a value to a custom user field

Discussion in 'XenForo Development Discussions' started by Marcel, Jul 26, 2015.

  1. Marcel

    Marcel Active Member

    Could someone point me in the right direction please?
    I've tried a multitude of ways and I just can't get my head round it

    I have an addon that creates a customfield, lets call it mycustomfield (A 3 digit integer).
    I have the value to be inserted stored in $myinteger

    I would have assumed it would be something along the lines of (For demonstration purposes)

    $userId = '1';
    $userModel = XenForo_Model::create('XenForo_Model_User');
    $userProfile = $userModel->getFullUserById($userId);
    $customFields = unserialize($userProfile['custom_fields']);

    $dwUser = XenForo_DataWriter::create('XenForo_DataWriter_User');

    errrr??

    $dwUser>save();
    return;


    Please note (if this makes a difference), this will be part of a cron job that will daily calculate the three digit integer based on posts over particular forums. That part of the code isn't ready yet.....I want to get this part done first.


    I've read Furhman's guide to using the datawriter, and Chris D's various guides, but I'm stuck at the moment.

    Thanks :)
     
  2. katsulynx

    katsulynx Well-Known Member

    PHP:
    $userId '1';
    $userModel XenForo_Model::create('XenForo_Model_User');
    $userProfile $userModel->getFullUserById($userId);
    $customFields unserialize($userProfile['custom_fields']);
    $customFields['mycustomfield'] = $myInteger;

    $dw XenForo_DataWriter::create('XenForo_DataWriter_User');
    $dw->setExistingData($userProfile);
    $dw->setCustomFields($customFields);
    $dw->save();
     
    Last edited: Jul 27, 2015
    NixFifty likes this.
  3. Marcel

    Marcel Active Member

    Fantastic, thankyou!
    Will report back tomorrow ...
     
  4. Marcel

    Marcel Active Member

    Sorry, me again!
    I'm stuck again. .
    PHP:
            $myinteger '777';
            
    $userId 1;

            
    $user $userModel->getFullUserById($userId);
            
    $userProfile $userModel->getFullUserById($userId);
            
    $customFieldsu unserialize($userProfile['custom_fields']);
            
    $customFieldsu['mycustomfield'] = $myinteger;
            
    $customFields = array(serialize($customFieldsu));
          
            
    $dw XenForo_DataWriter::create('XenForo_DataWriter_User');
            
    $dw->setExistingData($userProfile,true);
            
    $dw->setCustomFields($customFields);
            
    $dw->save();
            
    $dw->rebuildCustomFields();
    My understand of the process needed to be done is

    Get full user profile
    Unserialize the custom fields
    Insert myinteger into mycustomfield
    Reserialize the custom fields
    Insert all the user profile field back, set the custom fields (I'm a little confused at the two lines here. setExistingData seems to set the whole profile, then setCustomFields seems to re-set the custom fields)
    And save.

    But the damn thing just wont update the profile
     
  5. katsulynx

    katsulynx Well-Known Member

    Do not serialize your data again. The function setCustomFields does that for you and expects an array for a reason.

    With setExistingData you tell the XenForo DataWriter which profile to edit. Basically you could also only give him the user-id in form of array('user_id' => $userId) too. That function does not save anything, as the DataWriter itself will call the entry from the database with the id you've given him and sets all fields to their old values (as stored before your edit). After that we tell him that he needs to change something, doing so by using the function setCustomFields. This step is the first (and in this case only) step in which the DataWriter gets new data. If you'd save before that step, nothing would change.
     
  6. Marcel

    Marcel Active Member

    Thank you. I just assumed I had to serialize it again myself.
    So now we're back to

    PHP:
            $myinteger '777';
            
    $userId 1;

            
    $user $userModel->getFullUserById($userId);
            
    $userProfile $userModel->getFullUserById($userId);
            
    $customFields unserialize($userProfile['custom_fields']);
            
    $customFields['mycustomfield'] = $myinteger;
        
            
    $dw XenForo_DataWriter::create('XenForo_DataWriter_User');
            
    $dw->setExistingData($userProfile,true);
            
    $dw->setCustomFields($customFields);
            
    $dw->save();
            
    $dw->rebuildCustomFields();
    I've just realised. When extending the DataWriter_User, I extended the protected function _getFields to add my custom field, but I didn't extend the function _preSave. Is that where I've gone wrong?
    Apologies if this is a stupid question.
     
  7. katsulynx

    katsulynx Well-Known Member

    I am honestly a little confused what you mean. If you are storing the data into the custom fields, there is no need editing the DataWriter at all.
     
  8. Marcel

    Marcel Active Member

    Don't worry, I'm even more confused than you! :)
    Ignore the _preSave question.

    The code above is what I have now, but it just doesn't update and save the profile.

    Thank you for your help, it's appreciated.
     
  9. Marcel

    Marcel Active Member

    Nope, I'm stuck again :(
    I don't know why, but it's just not saving the value to the profile.

    I've split the code up a little and put the datawriter stuff in a separate file (This is the actual code now)

    PHP:
        $userProfile $userModel->getFullUserById($userId);
        
    $customFields unserialize($userProfile['custom_fields']);
        
    $customFields['mab_mod_cr'] = $ratio;

        
    $dw XenForo_DataWriter::create('XenForo_DataWriter_User');
        
    $dw->writeRatioToProfile($userProfile,$customFields);
    and

    PHP:
        public function writeRatioToProfile($userProfile$customFields)
        {
            
    $this->setExistingData($userProfile);
            
    $this->setCustomFields($customFields);
            
    $this->rebuildCustomFields();
            
    $this->save();       
            return;
        }
     
  10. Marcel

    Marcel Active Member

    BINGO!

    Found it! It's because the profile field isn't set as User Editable. As soon as I enable that, the value updates!
    I saw a thread discussing this issue earlier today and how to get round it (This is a private field, I don't want the users editing it of course).

    Thanks again :)
     
    katsulynx likes this.
  11. Jarvis

    Jarvis New Member

    Hi, sorry for pulling this back up.

    How did you get around being able to write values even if the field is private?
     
  12. Thomas.B

    Thomas.B Well-Known Member

    You need to enable the „admin edit“ option in the datawriter:
    Code:
    $userDw->setOption(XenForo_DataWriter_User::OPTION_ADMIN_EDIT, true);
     
  13. Marcel

    Marcel Active Member

    That must have been it! I honestly can't remember what I did, but looking at the code that's live....

    PHP:
        public function writeRatioToProfile($userProfile$customFields)
        {
            
    $this->setExistingData($userProfile);
            
    $this->setOption(XenForo_DataWriter_User::OPTION_ADMIN_EDITtrue);
            
    $this->setCustomFields($customFields);
            
    $this->rebuildCustomFields();
            
    $this->save();
            return;
        }
     

Share This Page