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.