Skip to content
Advertisement

Using Iterator and update_user_meta() to Dynamically Add Checkboxes to profile.php and edit-user.php in WordPress Using an Array

So, I’ve been pulling my hair out over this for longer than I’d care to admit. I am trying to create a bunch of checkboxes in profile.php and user-edit.php for a plugin that is populated by an array. For starters, this works:

//<!-- "HTML" -->
function profile_fields($user) {
    $user_id =  $user->ID;

    <input type='hidden' name="user_id" value="<?php echo $user_id ?>" />
    <input type="checkbox" id="some-setting" name='some-setting'
    <?php if (get_user_meta( $user->ID, 'somePref', true ) == '1'){ echo 'checked'; } ?> />
    <label for="some-setting">TEST 2</label>


//PHP
function update_field_value($user_id) {
    if ( isset($_POST['some-settings'], $user_id ) && $_POST['some-settings'] == 'on') { 
        update_user_meta( $user_id, 'somePref', '1'); 
    } else { 
        update_user_meta( $user_id, 'somePref', NULL); 
    }
}

HOWEVER, what I have generates Undefined offset... and Trying to access array offset on value of type null... that I can’t trace the origin of when using:

class Some_Class
   {


//Array of user specialties to be displayed
var $userSpecialtiesList;

//Array of ids for input fields
var $userSpecialtiesIDs = array();

//Array of meta values for input fields
var $metaValues = array();

//Array of meta value names for use with accessing info
var $metaNames = array();

/**
* initialize
*
* I use this to populate the array and call add_action 
*/
function initialize(){
   $this->userSpecialtiesList = array(
          /* some information here */
   );
   add_action( 'show_user_profile', array($this, 'extra_profile_fields') );
   add_action( 'edit_user_profile', array($this, 'extra_profile_fields') );
   add_action( 'personal_options_update', array($this, 'update_field_value') ); 
   add_action( 'edit_user_profile_update', array($this, 'update_field_value') );
}

/**
* extra_profile_fields
* I use this to generate the input fields that the user sees
*/
function extra_profile_fields( $user ) {
   $user_id =  $user->ID;

   //I used this for testing
   //$meta_value = get_user_meta( $user->ID, 'somePref', true );
   
   ?> 
   <h3><?php _e("Some Title", "blank"); ?></h3>
   <table class="form-table">
       <!-- Some unrelated stuff here -->
       <tr>
           <th><h4><?php _e("Specialties"); ?></h4></th>
           <td>
           <fieldset>
           <!-- Some more unrelated stuff here -->
           <?php
              $this->generateCheckboxes($user_id);?>
           </fieldset>
       </td>
     </tr>
   </table>
   <?php
}

/**
* generateID
*
* Partially complete function to generate field ids and meta keys
*/
function generateID($phrase, $arrValue, $style){
   //Remove illiegal characters and leave only alphanumeric
   $arrValueUpdated = preg_replace('/[^a-zA-Zd:]/', "", $arrValue);
   
   switch($style){
       //Use Dashes
       case $style == "-": 
       case $style == "dash":
           return strtolower($phrase) . "-" . strtolower($arrValueUpdated);
       
       //Use camelCase
       case $style == "camelCase":
           return strtolower($phrase) . ucfirst($arrValueUpdated);
       
       //Default is alltogether
       default:
           return strtolower($phrase) . strtolower($arrValueUpdated);  
   }
}

/**
* generateCheckboxes
* 
* I use this to generate checkboxes from the array instantiated above
*/
function generateCheckboxes($userID){
   
   foreach($this->userSpecialtiesList as $userSpecialty){
       //Create unique id for input fields and add it to array for later
       $inputID = $this->myGenerateID("specialty", $userSpecialty, "dash");
       array_push( $this->userSpecialtiesIDs, $inputID );
   
       
       
       //Create meta key and add it to array of meta keys for use with update_user_meta later
       $metaName = $this->myGenerateID("pref", $userSpecialty, "camelCase");
       array_push( $this->metaNames, $metaName );
       
       //Create variable for meta values and add it to array for later
       $meta_value = get_user_meta( $userID, $metaName, true );
       array_push( $this->metaValues, $meta_value );

?>
               <div class="my-checkbox-class">
                   <input type='hidden' name="user_id" value="<?php echo $userID ?>" />
                   <input type="checkbox" id="<?php echo $inputID; ?>" name='<?php echo $inputID; ?>'
                   <?php if ($meta_value == '1'){ echo 'checked'; } ?> />
                   <label for='<?php echo $inputID; ?>'><?php _e($userSpecialty); ?></label>
               </div>
   
<?php } 


function update_field_value($user_id) {
   $user_id = $_POST['user_id'];
   $uslIndex = 0;

   foreach($this->userSpecialtiesList as $userSpecialty){
       if ( isset($_POST[$this->userSpecialtiesIDs[$uslIndex]], $user_id ) && $_POST[$this->userSpecialtiesIDs[$uslIndex]] == 'on') { 
           update_user_meta( $user_id, $this->metaNames[$uslIndex], '1'); 
       } else { 
           update_user_meta( $user_id, $this->metaNames[$uslIndex], NULL); 
       }           
       $uslIndex++;
    }
 }
}
   function some_class_func() {
       global $some_class_func;

       // Instantiate only once.
       if( !isset($some_class_func) ) {
           $some_class_func = new Some_Class();
           $some_class_func->initialize();
       }
       
       return $some_class_func;
   }

   // Instantiate
   some_class_func();

In posting this, I obfuscated some of the variable names and removed some unnecessary bits for clarity; I also realize as I went through it that I have some artifacts from re-writing portions of it that may be part of my problem but I’ve chosen to leave them in.

If I get this on my own then I will post the solution for everyone; in any case though, I offer many thanks in advance for any and all answers / help!

Advertisement

Answer

Alright, so it seems like my problem was perhaps one of scope so what I did was basically just create an array elsewhere and hand it to the update function. So, I pretty much left initialize(), extra_profile_fields(), and generateID() alone and instead I made the following changes:

   //Generate the input tag ID and meta key / name 
   // and then create the HTML for checkboxes
   function generateCheckboxes($userID){
    
        foreach($this->userSpecialtiesList as $userSpecialty){
            $inputID = $this->generateID("specialty", $userSpecialty, "dash");
            $metaName = $this->generateID("pref", $userSpecialty, "camelCase"); ?>
                    <div class="prof-checkbox">
                        <input type='hidden' name="user_id" value="<?php echo $userID ?>" />
                        <input type="checkbox" id="<?php echo $inputID; ?>" name='<?php echo $inputID; ?>'
                        <?php if (get_user_meta( $userID, $metaName, true ) == '1'){ echo 'checked'; } ?> />
                        <label for='<?php echo $inputID; ?>'><?php _e($userSpecialty); ?></label>
                    </div>
    <?php } 
    }

   
   /**
    * generate_array()
    * Creates, populates, and returns a multi-dimensional array holding
    * the input tag's id, meta key, and text value.
    *
    * @return $userSpecialtiesArr Array    A multi-dimensional array holding the input tag's id ("id"), meta key "meta", and text "text"
    */
   function generate_array(){
        $userSpecialtiesArr = array();
        
        foreach($this->userSpecialtiesList as $userSpecialty){
            
            $userSpecialtyPKG = array(
                "text"=>$userSpecialty,
                "id"=>$this->HgenerateID("specialty", $userSpecialty, "dash"),
                "meta"=>$this->generateID("pref", $userSpecialty, "camelCase"),
            );
            
            array_push($userSpecialtiesArr, $userSpecialtyPKG);
        }
        return $userSpecialtiesArr;
    }


function update_field_value($user_id) {
        
        $user_id = $_POST['user_id'];
        //Generate array to hold the neccessary information
        $userSpecialtiesArr = $this->generate_array();
        
        //Use an iterator to dynamically add the necessary unique ID and meta key.
        foreach($userSpecialtiesArr as $userSpecialty) :
        
            if ( isset($_POST[$userSpecialty['id']], $user_id ) && $_POST[$userSpecialty['id']] == 'on') { 
                update_user_meta( $user_id, $userSpecialty['meta'], '1'); 
            } else { 
                update_user_meta( $user_id, $userSpecialty['meta'], NULL); 
            }
        
        endforeach;
    
    }

Not sure if this’ll help anyone, but if not Kinglish also had a pretty great answer and hopefully both can reduce somebody out there pulling out their hair over the same thing.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement