Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm at a loss. I've got a custom meta box with the 'multicheck' code that Jan created. It's working great. My issue now is getting the data to return properly.

Scenario: there are 5 possible values, each with the same meta_key. What I am trying to do is display specific content if a value is stored with one of the 5 possible values. What is happening is that the content is repeating.

Current site: http://dev.andrewnorcross.com/yoga/locations/tampa/

Current code:

    <?php
    global $post;
$offerings = get_post_meta($post->ID, "evol_offerings_select", false);
if ($offerings[0]=="") { ?>

<!-- If there are no custom fields, show nothing -->

<?php } else { ?>

<div class="offerings">
    <h3>offerings:</h3>
            <?php 
            foreach ($offerings as $offering) {
                if ($offering["hot"]==true) {
                    echo "<div class='single_offering'>";
                    echo "<h3>Hot 90</h3>";
                    echo "<p class='class_info'>temp: 105&deg;&nbsp;&nbsp;&nbsp;time: 90 min</p>";
                    echo '</div>';
                }
                if ($offering["flow"]==true) {
                echo "<div class='single_offering'>";
                echo "<h3>Flow 75</h3>";
                echo "<p class='class_info'>temp: 80&deg;&nbsp;&nbsp;&nbsp;time: 75 min</p>";
                echo '</div>';
                }
                if ($offering["warm"]==true) {
                echo "<div class='single_offering'>";
                echo "<h3>Warm 60</h3>";
                echo "<p class='class_info'>temp: 90&deg;&nbsp;&nbsp;&nbsp;time: 60 min</p>";
                echo '</div>';
                }
                if ($offering["chill"]==true) {
                echo "<div class='single_offering'>";
                echo "<h3>Chill 30</h3>";
                echo "<p class='class_info'>temp: 75-80&deg;&nbsp;&nbsp;&nbsp;time: 30 min</p>";                    
                echo '</div>';
                }
                if ($offering["kids"]==true) {
                echo "<div class='single_offering'>";
                echo "<h3>Kids Class</h3>";
                echo "<p class='class_info'>temp: comfy&nbsp;&nbsp;&nbsp;time: 60 min</p>";
                echo '</div>';
                }
                } ?>
share|improve this question
    
Can you include a link to the multicheck code you are using? I answered two different questions on it, and a link there could be useful for others with the same problem. –  Jan Fabry Jan 25 '11 at 9:13
add comment

4 Answers

up vote 3 down vote accepted

Your foreach is the problem. You're iterating once for each offering, yet you're evaluating ALL offering values in the array each time. So your PHP is dutifully printing all available offerings * the number of offerings. I'd say go without the foreach() and see what happens.

EDIT 1 Also please note, you're casting strings to arrays. You're trying to look up values in an array based on an invalid key. $offerings["hot"] - $offerings["kids"] don't exist, as far as PHP is concerned. $offerings[0] - $offerings[4] DO exist.

EDIT 2 Okay, you want the following in place of your foreach():

if(in_array("hot", $offerings)){
// print hot results
}

if(in_array("chill", $offerings)){
//print chill results
}

etc.

EDIT 3

Or, if I think about it further, you could stick with the foreach() in the following manner:

foreach($offerings as $offering){
 switch($offering){
   case "hot":
    //print hot stuff
   break;
   case "chill":
    //print chill stuff
   break;
 }
}

EDIT 4

If you were dealing with a larger data set, I would probably go with the switch() version, as the in_array() calls scan the whole array each time, which could get expensive, while the foreach() will simply iterate through the array and move the array pointer with each iteration. Your call, but I'm thinking that would be the way to go in order to future-proof and performance-proof. (The performance hit on a 5 value array for in_array() is likely minuscule, but these things add up.)

share|improve this answer
    
I thought the same thing. But removing that causes the content not to display at all. –  Norcross Jan 18 '11 at 21:43
    
BOOM! that's it. It works flawlessly and updates when choices are selected or de-selected. –  Norcross Jan 18 '11 at 22:14
add comment

Can you share the code that you are using to register those boxes? Sounds like each time you are saving, each value is overwriting each other. You will need to save the values into an array.

share|improve this answer
    
Box $meta_boxes[] = array( 'id' => 'offerings_select', 'title' => 'Available Offerings', 'pages' => array('locations'), // post type 'context' => 'normal', 'priority' => 'high', 'fields' => array( array( 'name' => 'Available Offerings', 'desc' => 'Select the offerings available at this location', 'id' => $prefix . 'offerings_select', 'type' => 'multicheck', 'options' => array( 'hot' => 'Hot 90', 'flow' => 'Flow 75', 'warm' => 'Warm 60', 'chill' => 'Chill 30', 'kids' => 'Kids Class', ) ) ) ); –  Norcross Jan 18 '11 at 21:36
    
The database it storing each value separately, so that's not a problem. I can look in the DB and see 5 entries for that post in the postmeta table with the same key. –  Norcross Jan 18 '11 at 21:38
    
what are the values in those rows in the db? –  cori Jan 18 '11 at 21:38
    
@Cori Here is what gets stored evol_offerings_select || hot evol_offerings_select || flow evol_offerings_select || warm evol_offerings_select || chill evol_offerings_select || kids –  Norcross Jan 18 '11 at 21:40
    
What's the returned data from print_r($offerings);? –  ZaMoose Jan 18 '11 at 21:46
show 5 more comments

PHP will evaluate

$offering["someKey"]==true

as true for a key so long as the value for that key is not empty, so I suspect get_post_meta() is returning something ("null" or even " ") for those values.

try using

$offering["someKey"]===true

for strict equality and it should work.

share|improve this answer
    
Almost. But changing it to $offering["hot"]=true cause them to appear, once, regardless of whether or not it was checked. Back to the drawing board. –  Norcross Jan 18 '11 at 21:49
    
Wait, what? $offering["hot"]=true; will assign the value "true" to the array entry keyed "hot". I don't think that's what you want... –  ZaMoose Jan 18 '11 at 21:50
    
That's the assignment operator. That's not the conditional inside an if() statement, is it? –  Annika Backstrom Jan 18 '11 at 21:52
    
I don't think that's right - if you do that you're setting the value of $offering["hot"] to boolean true. I'll admit, though, that I only tested the equality on an array I ginned up from scratch - not within wordpress, so there may be some dynamic that's making $offering["hot"]===true not work as I would expect. –  cori Jan 18 '11 at 21:52
    
Because if($offering["hot]=true) will always evaluate to "true" and the interior of the if{} statement will get executed. –  ZaMoose Jan 18 '11 at 21:53
show 6 more comments

Try this:

 <?php
    global $post;
    $offerings = get_post_meta($post->ID, "evol_offerings_select", false);
    $offeringDefinitions = array(
        'hot'   =>(object)array('name'=>'Hot 90',       'temp'=>'105',      'time'=>'90'),
        'flow'  =>(object)array('name'=>'Flow 75',      'temp'=>'80',       'time'=>'75'),
        'warm'  =>(object)array('name'=>'Warm 60',      'temp'=>'90',       'time'=>'60'),
        'chill' =>(object)array('name'=>'Chill 30',     'temp'=>'75-80',    'time'=>'30'),
        'kids'  =>(object)array('name'=>'Kids Class',   'temp'=>'comfy',    'time'=>'60')
    );
    $offeringsInUse = array();
    forEach($offerings as $offering) {
        forEach($offeringDefinitions as $offeringName=>$offeringDefinition) {
            if ($offering[$offeringName]) $offeringsInUse[$offeringName]=$offeringDefinition;
        }
    }
?>
<?php if (count($offeringsInUse)>0): ?>
    <div class="offerings">
        <h3>offerings:</h3>
        <?php forEach ($offeringsInUse as $offering): ?>
            <div class="single_offering">
                <h3><?php echo $offering->name ?></h3>
                <p class="class_info">temp: <?php echo $offering->temp ?>&deg;&nbsp;&nbsp;&nbsp;time: <?php echo $offering->time ?>min</p>
            </div>
        <?php endForEach ?>
    </div>
<?php endIf ?>

What I've done here is:

  1. Preset the defintions of the offering types. Ideally this would be data driven, but since it's obviously not, this is the best alternative.
  2. Check the definitions against the various offerings available per... offering*, and stack that into an array.
  3. If that array isn't empty, display the appropriate chunk of HTML, filling in the offering attributes as you iterate over the array.

*Actually, that's what I've gleaned from your suggested requirements - that a given program has a set of offered activities, and that these activities need to be enumerated... or something. Maybe you could be more clear.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.