Jump to content

fun and frolic with multi-dimensional arrays


ThunderVike

Recommended Posts

This has been so much FUN  :'( for me that I couldn't wait to share!

 

I have a page on a Wordpress site using some special functions in the Theme I am running that displays custom fields in a List after a Form has been filled out for a Particular Post Category.

 

On this page the User can see the results of the Form they just filled out and review them before finally submitting them.

 

I have one function which gathers all of the Custom fields associated with that particular post they have made from the "holding table"--an interim saving instead of keeping them all in a session value exclusively.

 

The form they have just filled out produces one string or value per field EXCEPT in the case of multi-value checkboxes.

 

If on this review page any values are gathered whose $field_type is equal to 'checkbox' then it is guaranteed that those values are stored in an array.  Right now the problem is that the existing function that gathers and displays all these custom fields simply shows "Array" everytime it handles the values of one of these checkboxes.

 

In those cases where a row's $field_type = 'checkbox' then in every case there will be an associative array stored in brackets [] that I want when detected to be put into visible list of however many values are found.

 

In the sql statement when it gathers the field $field_type values it will find either "text", "dropdown", "textarea", or "checkbox" in the same id row along with the $field_label, $field_name, $field_values for each record.

 

 

I want to build more conditions and actions here to handle a situation where it runs into an associative array inside the first array of all of the custom fields.

 

 

I include the whole function I want to modify further down:

It starts out --

        echo cp_formbuilder_review($results);

 

and I guess I want something along the lines of--

 

if($results) {foreach ($results as $result)

if (is_array($result) { loop through and put individual array elements in an unordered list with the $field_label associated with each checkbox array}

 

else { continue the loop for all other types of custom fields which are not $field_type=checkbox because all of these custom fields will have values in just one string or one value}

 

For testing purposes, so you know what the values look like underlying this page if I use this statement on the page

 

    echo '<br/><br/>("$postvals")-- $postvals PRINT<br/>';

    print_r;

 

I will get back this for $_POST

 

    echo '$_POST PRINT<br/>just the post and nothing more';

    print_r($_POST);

( [post_title] => Stunning rental [cp_checkbox_days] => Array (

  • => Thursday [1] => Friday ) [cp_checkbox_amenities] => Array (
  • => Gardener [1] => Watchman ) [cp_checkbox_hello] => Array (
  • => Smoking Allowed: Outdoor areas only ) [cp_price] => 98888 [cp_street] => 888 Flange [cp_city] => Reynaldo [cp_state] => Virginia [cp_country] => Antartica [cp_zipcode] => 1080 [tags_input] => stunner [post_content] => Wow is all we can say about this one.

 

Right now the visual display shows this for Arrays

<ul>

                    
        <li><label><strong>Category:</strong></label>
        <div id="review">Affordable Rentals</div>
            <div class="clr"></div>
        </li>

    
        <li>
            <label><strong>Title:</strong></label>

            <div id="review">Stunning stunner</div>
            <div class="clr"></div>
        </li>

    
        <li>
            <label><strong>help checkbox:</strong></label>
            <div id="review">Array</div>
            <div class="clr"></div>

        </li>

    
        <li>
            <label><strong>Staff Provided:</strong></label>
            <div id="review">Array</div>
            <div class="clr"></div>
        </li>

    
        <li>

            <label><strong>Suitability:</strong></label>
            <div id="review">Array</div>
            <div class="clr"></div>
        </li>

    
        <li>
            <label><strong>Price:</strong></label>
            <div id="review">98888</div>

            <div class="clr"></div>
        </li>

    
        <li>
            <label><strong>Street:</strong></label>
            <div id="review">888 Flange</div>
            <div class="clr"></div>
        </li>
</ul>

 

 

So, wherever a value shows up like this [cp_checkbox_days] => Array (

  • => Thursday [1] => Friday )  I need for this array to be iterated and broken up into <li>Thursday</li>

<li>Friday</li>

 

 

HERE IS THE CODE MORSEL that is UNDERPERFORMING!

 

I am hoping a genius like DavidAM can soup this thing up!

 

 

 

 

function cp_show_review($postvals) {
    global $wpdb;


    // if there's no form id it must mean the default form is being used so let's go grab those fields
    if(!($postvals['fid'])) {
        // use this if there's no custom form being used and give us the default form
        $sql = $wpdb->prepare("SELECT field_label, field_name, field_type, field_values, field_req "
             . "FROM ". $wpdb->prefix . "cp_ad_fields "
             . "WHERE field_core = '1' "
             . "ORDER BY field_id asc");

    } else {
        // now we should have the formid so show the form layout based on the category selected
        $sql = $wpdb->prepare("SELECT f.field_label,f.field_name,f.field_type,f.field_values,f.field_perm,m.meta_id,m.field_pos,m.field_req,m.form_id "
             . "FROM ". $wpdb->prefix . "cp_ad_fields f "
             . "INNER JOIN ". $wpdb->prefix . "cp_ad_meta m "
             . "ON f.field_id = m.field_id "
             . "WHERE m.form_id = '". $postvals['fid'] ."'"
             . "ORDER BY m.field_pos asc");
    }


    $results = $wpdb->get_results($sql);

    if($results) {

        // loop through the custom form fields and display them
        echo cp_formbuilder_review($results);

   //from here is where I have to switch to detecting the Arrays associated with checkboxes and explode them and loop them separately into something pretty with its own field_label   
//and when it has looped through all the Arrays and made them visible it continues looping through the rest of the single value strings and fields

    } else {

        echo sprintf(__('ERROR: The form template for form ID %s does not exist or the session variable is empty.', 'cp'), $postvals['fid'] . "\n\n");
    }
    ?>

 

Looks pretty darn easy doesn't it??

 

 

Link to comment
Share on other sites

Ooops,  OKAY...her is the Other part !

 

// loops through the custom fields and builds the step2 review page
function cp_formbuilder_review($results) {
    global $wpdb;
    ?>

        <li><label><strong><?php _e('Category','cp');?>:</strong></label>
        <div id="review"><?php echo $_POST['catname']; ?></div>
            <div class="clr"></div>
        </li>

    <?php
    foreach ($results as $result) {
    ?>

        <li>
            <label><strong><?php echo $result->field_label; ?>:</strong></label>
            <div id="review"><?php echo stripslashes(nl2br($_POST[$result->field_name])); ?></div>
            <div class="clr"></div>
        </li>

    <?php
    }

}

Link to comment
Share on other sites

Try the following function

// loops through the custom fields and builds the step2 review page
function cp_formbuilder_review($results)
{
    global $wpdb;
    ?>

        <li><label><strong><?php _e('Category','cp');?>:</strong></label>
        <div id="review"><?php echo $_POST['catname']; ?></div>
            <div class="clr"></div>
        </li>

    <?php
    foreach ($results as $result)
    {
        $form_field_value = $_POST[$result->field_name];
        if(is_array($form_field_value)
        {
            $field_review_value = '<ul><li> ' . implode('</li><li>', $form_field_value) . ' </li></ul>';
        }
        else
        {
            $field_review_value = stripslashes(nl2br($form_field_value));
        }
    ?>

        <li>
            <label><strong><?php echo $result->field_label; ?>:</strong></label>
            <div id="review"><?php echo $field_review_value; ?></div>
            <div class="clr"></div>
        </li>

    <?php
    }

}

Link to comment
Share on other sites

;D  Way to GO Wildteen!

 

I only had to jigger up one line to make this work!

 

 

        $form_field_value = $_POST[$result->field_name];
        if(is_array($form_field_value)

 

I just had to close up that second line with one more )

 

 

if(is_array($form_field_value))

 

It works great now!  THANK YOU for your GENEROUS DONATION of TIME and EXPERIENCE !  And BRAINS !

 

 

Link to comment
Share on other sites

Wildteen88, since that was so brilliant, let me run this past you--

 

The code you have just solved is for a review page...if the page is okay the User Hits the Submit button and the whole thing is saved again--permanently, so to speak.

 

In that table where this will next be saved -- "wp_postmeta" are the following fields:

 

meta_id post_id meta_key   meta_value

 

Where the $meta_key value is something like 'cp_checkbox_amenities' or whatever other checkboxes are used such as 'cp_checkbox_days'

 

the $meta_value field should have a comma delimited array such as "Sunday, Tuesday, Thursday"--any value checked off appears here.

 

I have used a hard-coded series of lines to do this on this page because I knew ahead of time that this page would use these checkbox forms--

 

   $postvals['cp_checkbox_amenities']= implode(',', $_POST['cp_checkbox_amenities']);
   $postvals['cp_checkbox_days']= implode(',', $_POST['cp_checkbox_days']);
   $postvals['cp_checkbox_three']= implode(',', $_POST['cp_checkbox_three]);

 

But I don't want to hardcode this for all the checkboxes that I will use in the future... I want to get rid of this code and use the same IMPLODE function to SAVE the internal arrays with commas.  Every time I have an array within an array I want  the internal array to be saved and edited with a simple comma separating each value in an array.

 

Using something similar to your code how can I now permanently convert these internal arrays, the same ones you have addressed with your previous code, IMPLODING the way I show above, but without knowing whether it is applied to $_POST['cp_checkbox_amenities'] or some other checkbox variable?

 

To help you understand there is a function that the postvals are submitted to for saving and updating the table and here is the function within that function (created by DavidAM here at PHPFreaks) that detects the data coming from a string that has the $meta_key starting with a cp_checkbox....so this function ASSUMES that the string being passed is already serialized (and it should be done with commas the way my hard-code has been doing it for the moment).

 

 

    // now add all the custom fields into WP post meta fields
    foreach($advals as $meta_key => $meta_value) {
        if (cp_str_starts_with($meta_key, 'cp_'))	
            add_post_meta($post_id, $meta_key, $meta_value, true);
  if(cp_str_starts_with($meta_key, 'cp_checkbox')) {
unserialize($meta_value);
add_post_meta($post_id, $meta_key, $meta_value, true);}
    }

 

Wildteen88, maybe you don't need to know that, but, at any rate, I just need to now CHANGE the internal arrays with IMPLODE with commas after your function first displays them as List items.

 

Thank you for such help!

 

Link to comment
Share on other sites

If I'm understanding that loop correctly. You could check to see if $meta_value is an array when checking to see if $meta_key starts with cp_checkbox. If $meta_key does start with cp_checkbox and is an array then you can implode the values into a comma delimited list. So you'd change this

	  if(cp_str_starts_with($meta_key, 'cp_checkbox')) {
unserialize($meta_value);
add_post_meta($post_id, $meta_key, $meta_value, true);}

 

To

	  if(cp_str_starts_with($meta_key, 'cp_checkbox') && is_array($meta_value)) {
        // implode the values into a comma delimited list
$meta_value = implode(', ', $meta_value);
add_post_meta($post_id, $meta_key, $meta_value, true);}

Link to comment
Share on other sites

Thank you, wildteen88!

 

I put that in but after I reviewed a New test Ad that had used checkboxes that collected values into an array and updated it it returned simply ARRAY for those checkbox fields.

 

Yet, your looping function displayed that those checkbox arrays had values that your function displayed in separate lines: <ul><li>Value one</li><li>Value two</li><li>Value three</li>

 

But now with this new function in the ad saved with just "Array" in the checkbox values.

 

Maybe it would be clearer to you if I posted most of the page where I put your newest function:

 

 

* here we are processing the images and gathering all the post values.
* using sessions would be the optimal way but WP doesn't play nice so instead
* we take all the form post values and put them into an associative array
* and then store it in the wp_options table as a serialized array. essentially
* we are using the wp_options table as our session holder and can access
* the keys and values later and process the ad in step 3
*
*/

global $userdata;
global $wpdb;

// check to see if there are images included
// then valid the image extensions
if (!empty($_FILES['image']))
    $error_msg = cp_validate_image();

// images are valid
if(!$error_msg) {

    // create the array that will hold all the post values
    $postvals = array();

    // upload the images and put into the new ad array
    if (!empty($_FILES['image']))
        $postvals = cp_process_new_image();

    // keep only numeric, commas or decimal values
    if (!empty($_POST['cp_price']))
        $postvals['cp_price'] = cp_clean_price($_POST['cp_price']);
    
    // keep only values and insert/strip commas if needed
    if (!empty($_POST['tags_input']))
        $postvals['tags_input'] = cp_clean_tags($_POST['tags_input']);

    // put all the posted form values into session vars
    foreach($_POST as $key => $value)
        $postvals[$key] = cp_clean($value);

$postid = ($_POST['fid']);
$catid = ($_POST['cat']);
// store the user IP address, ID for later
    $postvals['cp_sys_userIP'] = cp_getIP();
    $postvals['user_id'] = $current_user->ID;

    // see if the featured ad checkbox has been checked
    if ($_POST['featured_ad']) {
        $postvals['featured_ad'] = $_POST['featured_ad'];
        // get the featured ad price into the array
        $postvals['cp_sys_feat_price'] = get_option('cp_sys_feat_price');
    }

    // calculate the ad listing fee and put into a variable
    if(get_option('cp_charge_ads') == 'yes')
        $postvals['cp_sys_ad_listing_fee'] = cp_ad_listing_fee($_POST['cat'], $_POST['ad_pack_id'], $_POST['cp_price']);

    // check to prevent "Notice: Undefined index:" on php strict error checking. get ad pack id and lookup length
    $adpackid = '';
    if(isset($_POST['ad_pack_id'])) {
        $adpackid = $_POST['ad_pack_id'];
        $postvals['pack_duration'] = cp_get_ad_pack_length($adpackid);
    }

    // calculate the total cost of the ad
    $postvals['cp_sys_total_ad_cost'] = cp_calc_ad_cost($_POST['cat'], $adpackid, $postvals['cp_sys_feat_price'], $_POST['cp_price']);
    // Debugging section
    //echo '$_POST ATTACHMENT<br/>';
    //print_r($postvals['attachment']);

    //echo '$_POST PRINT<br/>';
    //print_r($_POST);

    //echo '<br/><br/>$postvals PRINT<br/>';
    //print_r($postvals);

    // now put the array containing all the post values into the database
    // instead of passing hidden values which are easy to hack and so we
    // can also retrieve it on the next step

    foreach($postvals as $meta_key => $meta_value) {
  if(cp_str_starts_with($meta_key, 'cp_checkbox') && is_array($meta_value)) {
        // implode the values into a comma delimited list
$meta_value = implode(', ', $meta_value);
add_post_meta($post_id, $meta_key, $meta_value, true);}
} 

//  I am posting this comment, Wildteen88, to point out this is where my hardcoded function
//   was sitting that did exactly what I needed, converting the checkbox arrays into a comma delimited string
//  I removed the following 3 lines to test your function and that's when I discovered that these
//  checkbox arrays were unaffected by your rewritten function above

//   $postvals['cp_checkbox_amenities']= implode(',', $_POST['cp_checkbox_amenities']);
//   $postvals['cp_checkbox_days']= implode(',', $_POST['cp_checkbox_days']);
//   $postvals['cp_checkbox_three']= implode(',', $_POST['cp_checkbox_three]);


    $option_name = 'cp_'.$postvals['oid'];
    update_option($option_name, $postvals);

    ?>

    <div id="step2"></div>

      <h2 class="dotted"><?php _e('Review Your Listing','cp');?></h2>

            <img src="<?php bloginfo('template_url'); ?>/images/step2.gif" alt="" class="stepimg" />
<?php // this is where the completed form first comes back to look at while in the add new ad process ?>

            <form name="mainform" id="mainform" class="form_step" action="" method="post" enctype="multipart/form-data">


  
                <ul>

                    <?php
                    // pass in the form post array and show the ad summary based on the formid
                    echo cp_show_review($postvals);

                    // debugging info

                    // debugging info
                    //echo get_option('cp_price_scheme') .'<-- pricing scheme<br/>';
                    //echo $postvals['cat'] .'<-- catid<br/>';
                    //echo get_option('cp_cat_price_'.$postvals['cat']) .'<-- cat price<br/>';
                    //echo $postvals['user_id'] .'<-- userid<br/>';
                    //echo get_option('cp_price_per_ad') .'<-- listing cost<br/>';
                    //echo get_option('cp_curr_symbol_pos') .'<-- currency position<br/>'; 
?>
				                <li>
                <?php 
if($postvals['cp_sys_total_ad_cost'] > 0) : ?>
                <label><?php _e('Payment Method','cp'); ?>:</label>
                <select name="cp_payment_method" class="dropdownlist required">
                    <?php if(get_option('cp_enable_paypal') == 'yes') { ?><option value="paypal"><?php echo _e('PayPal', 'cp') ?></option><?php } ?>
                    <?php if(get_option('cp_enable_gcheckout') == 'yes') { ?><option value="gcheckout"><?php echo _e('Google Checkout', 'cp') ?></option><?php } ?>
                    <?php if(get_option('cp_enable_2checkout') == 'yes') { ?><option value="2checkout"><?php echo _e('2Checkout', 'cp') ?></option><?php } ?>
                    <?php if(get_option('cp_enable_authorize') == 'yes') { ?><option value="authorize"><?php echo _e('Authorize.net', 'cp') ?></option><?php } ?>
                    <?php if(get_option('cp_enable_chronopay') == 'yes') { ?><option value="chronopay"><?php echo _e('Chronopay', 'cp') ?></option><?php } ?>
                    <?php if(get_option('cp_enable_mbookers') == 'yes') { ?><option value="mbookers"><?php echo _e('MoneyBookers', 'cp') ?></option><?php } ?>
                </select>
                <?php endif; ?>
                <div class="clr"></div>
                </li> 

?>
                </ul>

                <div class="pad10"></div>


	<div class="license">

                    <?php echo get_option('cp_ads_tou_msg'); ?>

	</div>

                <div class="clr"></div>


                <p class="light"><?php _e('By clicking the proceed button below, you agree to our terms and conditions.','cp'); ?>
                <br/>
                <?php _e('Your IP address has been logged for security purposes:','cp'); ?> <?php echo $postvals['cp_sys_userIP']; ?></p>


                <p class="btn2">
                    <input type="button" name="goback" class="btn_orange" value="<?php _e('Go back','cp') ?>" onclick="history.back()" />
                    <input type="submit" name="step2" id="step2" class="btn_orange" value="<?php _e('Proceed ','cp'); ?> ››" />
                </p>

                    <input type="hidden" id="oid" name="oid" value="<?php echo $postvals['oid']; ?>" />

    </form>

 

 

Does this hinge on using the brackets to define the array saved by checkboxes?

 

here's the generated code showing for just one of many possible multi-value checkboxes where the array is collected by the cp_checkbox_help[] or cp_checkbox_amenties...etc  etc...

 

<li>

            <label>help checkbox: </label>
  
              <input type="checkbox" name="cp_checkbox_help[]" value="Sunday">Sunday<br> 
                
              <input type="checkbox" name="cp_checkbox_help[]" value=" Monday"> Monday<br> 
                
              <input type="checkbox" name="cp_checkbox_help[]" value=" Tuesday"> Tuesday<br> 
              
              <input type="checkbox" name="cp_checkbox_help[]" value=" Wednesday"> Wednesday<br> 

              <input type="checkbox" name="cp_checkbox_help[]" value=" Thursday"> Thursday<br> 

              <input type="checkbox" name="cp_checkbox_help[]" value=" Friday"> Friday<br> 
                
              <input type="checkbox" name="cp_checkbox_help[]" value=" Saturday"> Saturday<br> 

       	
            <div class="clr"></div>

        
        </li>

 

Link to comment
Share on other sites

wildteen88, I am sure I confused you with one thing

 

The form is a multi step process...

 

1. Post or Ad Category selected  (functions find the appropriate form for this category and return the standard form fields as well as looping through to find all Custom fields that also help to make up this form to fill out)

 

2. The Form is assembled and displayed with open fields for filling out online.  (wherever the Form produces my different multi-value checkboxes which were stored with other Custom fields I have the values stored used the name of the checkbox  -- cp_checkbox_amenities, for instance)

 

3. The form is filled, the checkboxes are selected or left blank and Submit is pressed

 

4. The page returns for a Final Review of what was selected and written into the Form.  NOW, thanks to your function when the sub-arrays (is that what these are called?) are encountered that are created by the checkboxes your function loops them into separate lines to review while showing the label of the Checkbox...such as "Amenities"

 

5. If this is okay the User hits Submit, the final Submit, and the next message is that the Ad / Post is saved and is awaiting approval by the Admin.

 

6. AT THIS POINT the user can still click in his or her own "dashboard" on the ad just created and EDIT again.

 

7. It is HERE, in the EDIT AD "form" or page where THIS code comes in handy --- this code is written to OVERWRITE any EMPTY checkboxes.....if the user now UNSELECTS ALL CHECKBOXES in "Amenities" 'cp_checkbox_amenities'  and Updates the ad this function will find the EMPTY checkboxes and UNSERIALIZE the PREVIOUS array.

 

 

	  if(cp_str_starts_with($meta_key, 'cp_checkbox')) {
unserialize($meta_value);
add_post_meta($post_id, $meta_key, $meta_value, true);}

 

So that is what is for, one step later in the process.....

 

I still need to separately IMPLODE and comma delimit the checkbox arrays for the very first time.

 

I apologize for confusing you.

 

So, a dynamic way to do the same thing as the hard code...

 

 

 

   $postvals['cp_checkbox_amenities']= implode(',', $_POST['cp_checkbox_amenities']);
   $postvals['cp_checkbox_days']= implode(',', $_POST['cp_checkbox_days']);
   $postvals['cp_checkbox_three']= implode(',', $_POST['cp_checkbox_three]);

 

 

 

 

Link to comment
Share on other sites

I GOT IT....thanks for all your help!

 

I created a function that finds the checkbox names I need and loops through them and creates the implode action needed to assign comma delimited values to each checkbox.

 

On the actual form page I put in a reference to this function just before the last update option--

 


  cp_show_form_checkboxes($catid);	

    $option_name = 'cp_'.$postvals['oid'];
    update_option($option_name, $postvals);

 

 

and the function that this refers to is this below  in another functions php file :

 

 

// queries the db for the custom ad form based on the cat id and shows any checkboxes
function cp_show_form_checkboxes($catid) {
    global $wpdb;
    $fid = '';

    // get the category ids from all the form_cats fields.
    // they are stored in a serialized array which is why
    // we are doing a separate select. If the form is not
    // active, then don't return any cats.

    $sql = "SELECT ID, form_cats "
         . "FROM ". $wpdb->prefix . "cp_ad_forms "
         . "WHERE form_status = 'active'";

    $results = $wpdb->get_results($sql);

    if($results) {

        // now loop through the recordset
        foreach ($results as $result) {

            // put the form_cats into an array
            $catarray = unserialize($result->form_cats);

            // now search the array for the $catid which was passed in via the cat drop-down
            if (in_array($catid,$catarray)) {
                // when there's a catid match, grab the form id
                $fid = $result->ID;

                // put the form id into the post array for step2
                $_POST['fid'] = $fid;
            }

        }
  
        // now we should have the formid so show the form layout based on the category selected
        $sql = $wpdb->prepare("SELECT f.field_label, f.field_name, f.field_type, f.field_values, f.field_perm, m.meta_id, m.field_pos, m.field_req, m.form_id "
             . "FROM ". $wpdb->prefix . "cp_ad_fields f "
             . "INNER JOIN ". $wpdb->prefix . "cp_ad_meta m "
             . "ON f.field_id = m.field_id "
             . "WHERE f.field_type = 'checkbox' " 
 . "AND m.form_id = '$fid' "
             . "ORDER BY m.field_pos asc");

        $results = $wpdb->get_results($sql);

        if($results) {

        foreach ($results as $result):
            // now grab the field name

$postvals[$result->field_name]= implode(',', $_POST[$result->field_name]);

endforeach; 
}
     else {
      echo __('No checkbox details found.', 'cp');
    }

}

}

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.