Support

Account

Home Forums General Issues Multiple Select User Field and update_field()

Solved

Multiple Select User Field and update_field()

  • Hello,

    I am having a difficult time understanding how to update a Multiple Select User Field type using the update_field() function.

    To begin, I set up my Custom Field with the Field Label ‘Roster’ and Field Name ‘cb_roster’ and choose User as the Field Type and Multi Select as the second Field Type. I navigate to my Post, scroll down to the Custom Fields section, and in my Roster Custom Field, I am presented with a list of registered users. I selected a test account, “test01”, and Update my Post.

    In my child-theme PHP, I call:

    $roster = get_field('cb_roster');
    print_r($roster);

    Which returns the following array:
    Array ( [0] => Array ( [ID] => 24 [user_firstname] => Test [user_lastname] => McTest [nickname] => Test McTest [user_nicename] => test01 [display_name] => Test McTest [user_email] => [user_url] => [user_registered] => 2017-09-15 19:16:57 [user_description] => [user_avatar] => ) )

    I then turned to users.php (located in /plugins/advanced-custom-fields/core/fields) for a reference on how User fields were being populated in the default array output provided above.

    With that knowledge in mind, I then utilized some of the code to generate additional user information, in this case I froze the $value to 21 to capture a specific user for testing purposes:

    $value = '21';
    
      // format value
      if( !$value || $value == 'null' )
      {
        return false;
      }
    
      // temp convert to array
      $is_array = true;
    
      if( !is_array($value) )
      {
        $is_array = false;
        $value = array( $value );
      }
    
      foreach( $value as $k => $v )
      {
        $user_data = get_userdata( $v );
    
        //cope with deleted users by @adampope
        if( !is_object($user_data) )
        {
          unset( $value[$k] );
          continue;
        }
    
        $value[ $k ] = array();
        $value[ $k ]['ID'] = $v;
        $value[ $k ]['user_firstname'] = $user_data->user_firstname;
        $value[ $k ]['user_lastname'] = $user_data->user_lastname;
        $value[ $k ]['nickname'] = $user_data->nickname;
        $value[ $k ]['user_nicename'] = $user_data->user_nicename;
        $value[ $k ]['display_name'] = $user_data->display_name;
        $value[ $k ]['user_email'] = $user_data->user_email;
        $value[ $k ]['user_url'] = $user_data->user_url;
        $value[ $k ]['user_registered'] = $user_data->user_registered;
        $value[ $k ]['user_description'] = $user_data->user_description;
        $value[ $k ]['user_avatar'] = get_avatar( $v );
    
      }
    
      // de-convert from array
      if( !$is_array && isset($value[0]) )
      {
        $value = $value[0];
      }

    Then I run the following script to check my updated array has the same data types and format as the original array –

     ?>
      <h1>ARRAY TYPE OUTPUT FOR VALUE</h1>
      <?php
      foreach ( $value as $v ) {
      echo gettype($v), "\n";
      }
      ?><br><br><br><br><br><br>
    
      <h1>ARRAY TYPE OUTPUT FOR ROSTER</h1>
      <?php
      foreach ( $roster as $r ) {
        foreach ($r as $d) {
          echo gettype($d), "\n";
        }
      }?><br><br><br><br><br><br>
    
      <h1>VALUE OUTPUT</h1>
      <?php
      print_r($value);
    
      ?><br><br><br><br><br><br>
    
      <h1>ROSTER OUTPUT</h1>
      <?php
      print_r($roster);
      ?>

    I confirm that every data type is a string, and that my updated array has the same structure as the default array.

    Next, I want to add my updated array to the default array. So I run the following script:

    array_push($roster, $value);
    print_r($roster);

    And I get the following multidimensional array:

    Array ( [0] => Array ( [ID] => 24 [user_firstname] => Test [user_lastname] => McTest [nickname] => Test McTest [user_nicename] => test01 [display_name] => Test McTest [user_email] => [user_url] => [user_registered] => 2017-09-15 19:16:57 [user_description] => [user_avatar] => ) [1] => Array ( [ID] => 21 [user_firstname] => john [user_lastname] => [nickname] => johndoe [user_nicename] => johndoe [display_name] => johndoe [user_email] => [user_url] => [user_registered] => 2017-09-05 00:37:42 [user_description] => [user_avatar] => ) )

    Finally, I run:
    update_field('cb_roster', $roster);

    As a result, I expect the Multiple Select User Field to be updated with the additional User, “johndoe”. Instead, if I run:

    $roster = get_field('cb_roster');
    print_r($roster);

    The output ends up being:

    Array ()

    If I manually select ‘test01’ and ‘johndoe’ within the Multiple Select User field for the Post, and run my script:

    $roster = get_field('cb_roster');
    print_r($roster);

    The output ends up as:

    Array ( [0] => Array ( [ID] => 24 [user_firstname] => Test [user_lastname] => McTest [nickname] => Test McTest [user_nicename] => test01 [display_name] => Test McTest [user_email] => [user_url] => [user_registered] => 2017-09-15 19:16:57 [user_description] => [user_avatar] => ) [1] => Array ( [ID] => 21 [user_firstname] => john [user_lastname] => [nickname] => johndoe [user_nicename] => johndoe [display_name] => johndoe [user_email] => [user_url] => [user_registered] => 2017-09-05 00:37:42 [user_description] => [user_avatar] => ) )

    Which is exactly the same as the output of my scripted multidimensional array.

    Any input is greatly appreciated! Thanks in advance!

  • My apologies, I knew in my wall of text I would omit things. That code in its entirety is actually –

      $value = '21';
    
      // format value
      if( !$value || $value == 'null' )
      {
        return false;
      }
    
      // temp convert to array
      $is_array = true;
    
      if( !is_array($value) )
      {
        $is_array = false;
        $value = array( $value );
      }
    
      foreach( $value as $k => $v )
      {
        $user_data = get_userdata( $v );
    
        //cope with deleted users by @adampope
        if( !is_object($user_data) )
        {
          unset( $value[$k] );
          continue;
        }
    
        $value[ $k ] = array();
        $value[ $k ]['ID'] = $v;
        $value[ $k ]['user_firstname'] = $user_data->user_firstname;
        $value[ $k ]['user_lastname'] = $user_data->user_lastname;
        $value[ $k ]['nickname'] = $user_data->nickname;
        $value[ $k ]['user_nicename'] = $user_data->user_nicename;
        $value[ $k ]['display_name'] = $user_data->display_name;
        $value[ $k ]['user_email'] = $user_data->user_email;
        $value[ $k ]['user_url'] = $user_data->user_url;
        $value[ $k ]['user_registered'] = $user_data->user_registered;
        $value[ $k ]['user_description'] = $user_data->user_description;
        $value[ $k ]['user_avatar'] = get_avatar( $v );
    
      }
    
      // de-convert from array
      if( !$is_array && isset($value[0]) )
      {
        $value = $value[0];
      }

    Sorry about that.

    So this was my code, but my issue from before still stands. I wouldn’t be able to output the array of $value and check the types using gettype as I previously mentioned if this was not the case.

    I updated my original post to reflect this, so it’s not confusing to someone reading it for the first time. Thanks!

  • Okay, here’s the ultimate test in my opinion, and I have it narrowed down to my approach being completely wrong. The only problem is, I don’t know why it’s wrong?

    If I run:

    $roster = get_field('cb_roster');
    print_r($roster);
    
    update_field('cb_roster', $roster);

    And then after that script runs, I check the field:

    $roster = get_field('cb_roster');
    print_r($roster);

    I get the output:
    Array ()

    What am I missing? To me, this is like being handed a box with a ball inside. I open the box, put the ball on the table. I put the ball back in the box, and now the box is empty…

    Any help is greatly appreciated.

  • I got it… Turns out I was thinking too hard…

    I re-read the documentation for get_fields().

    Answer was that I don’t need to provide the full array as I was doing. Instead, the answer was to return ‘cb_roster’ like so:

    $roster = get_fields('cb_roster', false, false);
    print_r($roster);

    Which returns the array without formatting. The array without formatting looks like this:

    Array([0]=>24)

    Therefore, I only need to pass this script:

    $value = '21';
    
      array_push($roster, $value);
      update_field('cb_roster', $roster);

    Sorry for the confusion…

  • So, I’m a little late here and you already figure it out.

    The explanation is that when using update_field() you must supply the value as ACF stores the value. In this case you are using a user field and the value stored is an array of user IDs and not an array of user objects.

    Most of the more advanced fields require you to know what ACF actually stores and like you discovered, you can figure out what ACF actually stores by getting the unformatted value by supplying the 3rd parameter in get_field(). Another way to do this is to search the database.

  • I just have a quick follow-up question to this original question, and didn’t want to clutter the forum with additional posts. If I should make an additional post, please let me know.

    So everything is working perfectly fine up until this point. I am able to add and remove Users as I please, so long as the User Field is initially populated in the Post.

    However, when using a Multiple Select User Field, if no User is initially populated in the Post, and the following command is run:

    $test = get_field('cb_roster', false, false);
    print_r($test);

    This returns nothing at all. Therefore, if I use something like:
    array_push($test, $current_user);

    Nothing will happen (since it doesn’t exist).

    So, if I run the following:

    $current_user = get_current_user_id();
    $current_user = strval($current_user); //converting to string just in case
    
    $test = get_field('cb_roster', false, false);
    $current_user = array($current_user);
    print_r($test);
    print_r($current_user);
    
    update_field('cb_roster', $current_user);

    And then run:

    $test = get_field('cb_roster', false, false);
    print_r($test);

    I get a blank value (as though it does not exist).

    The output for print_r($current_user) returns:
    Array ( [0] => 24 )

    Which matches the format of the Array if it were populated from the Post.

    Any input is greatly appreciated!

  • When there is no value already existing for an ACF field what you need to do is use the field key instead of the field name. The field key should always be used when dealing with update_field(). The documentation here on this site show using the field name, but there is always the problem of ACF fields that have not been saved yet unable to return a value.

    
    $current_user = get_current_user_id();
    $current_user = strval($current_user); //converting to string just in case
    
    // use field key here
    $test = get_field('field_12345abcde', false, false);
    $current_user = array($current_user);
    print_r($test);
    print_r($current_user);
    
    // use field key here
    update_field('field_12345abcde', $current_user);
    
Viewing 8 posts - 1 through 8 (of 8 total)

You must be logged in to reply to this topic.