skip to Main Content

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!

2

Answers


  1. Chosen as BEST 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.


  2. Sometimes its easier to troubleshoot if you separate things out

    $postval = isset($this->userSpecialtiesIDs[$uslIndex]) ? $this->userSpecialtiesIDs[$uslIndex] : null;
    $user_id = $user_id ?? null;
    
    $condition1 = $user_id && $postval && isset($_POST[$postval]);
    $condition2 = $postval && $_POST[$postval] === 'on';
    
    if ($condition1 && $condition2) {
    // do the thing
    }
    

    and…

    if ($user_id && isset($this->metaNames[$uslIndex])) update_user_meta( $user_id, $this->metaNames[$uslIndex], NULL); 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search