By Shaun21uk


2019-05-13 18:19:54 8 Comments

A little long-winded but trying to explain clearly :)

I am delving into the code of my new theme and am not familiar with this type of data storing/pulling - can someone help me understand what is going on here please:

I am trying to create a page which outputs only the posts which have a 'coupon' attached to it. 'Coupon' is stored as a meta_key against a post.

It's meta_value is stored as an array which looks like this (output using print_r):

a:7:{s:9:"highlight";s:14:"Test Highlight";s:5:"title";s:12:"50% off food";s:11:"description";s:16:"Test description";s:4:"code";s:7:"1524521";s:11:"popup_image";s:4:"4548";s:17:"popup_description";s:17:"Popup description";s:11:"redirect_to";s:0:"";}

I want the custom page to output:

  • Post title
  • Post content
  • Post image
  • Coupon details

I can output the first three by running a wp_query:

$q = new WP_Query(array(
    'post_type' => 'listing',
    'posts_per_page' => 5,
    'meta_key' => 'wc_coupon',
    'meta_value' => ' ',
    'meta_compare' => '!='
));

However, I cannot find a way to split out the meta_value array to display the individual elements per post.


The theme handles this in a way I don't understand, perhaps someone can explain it to me.

Coupon.php is a partial file which is used when displaying any single post which looks like this:

global $post, $Args;
use ListingTools\Framework\Helpers\GetSettings;

$aCoupon = GetSettings::getPostMeta($post->ID, 'coupon');
if ( empty($aCoupon) || ( empty($aCoupon['code']) && empty($aCoupon['redirect_to']) ) ){
    return '';
}
?>

<div class="content-box_module__333d9">
    <div class="content-box_body__3tSRB">
        <?php echo do_shortcode('[get_coupon highlight="'.esc_attr($aCoupon['highlight']).'" title="'.esc_attr($aCoupon['title']).'" description="'.esc_attr($aCoupon['description']).'" code="'.esc_attr($aCoupon['code']).'" redirect_to="'.esc_attr($aCoupon['redirect_to']).'"]'); ?>
    </div>
</div>

So I don't understand how the "use" code works at the top in the variables section.

I also don't understand how the $aCoupon = GetSettings::getPostMeta($post->ID, 'coupon'); is working, but they can use this to display the individual parts of the coupon array as you can see later in the code:

echo do_shortcode('[get_coupon highlight="'.esc_attr($aCoupon['highlight'])

Hopefully that was follow-able :)

Thanks in advance.

2 comments

@Warwick 2019-05-13 20:18:35

The string you are outputting using print_r() is what is known as a serialized string. When WordPress stores an array of values in 1 custom field, it compresses the array into this string using a function called serialize()

What you want to do is to unserialize the string, and then you can access each "associated index" in the array.

Usually get_post_meta() unserializes the string for you, but it looks like the custom function GetSettings::getPostMeta() does not. In this case we can run maybe_unserialize() which will convert it into a usable array if it is able to.

Then we can simply loop through the array, outputting what you need to.

$aCoupon = GetSettings::getPostMeta($post->ID, 'coupon');
$aCoupon = maybe_unserialze( $aCoupon );
if ( empty( $aCoupon ) ){
    foreach ( $aCoupon as $key => $value ) {
        echo '<div><span class="label">' . $key . '</span> ' . $value . '</div>';
    }
}

Based on your example, it would output something like this.

<div><span class="label">highlight</span> Test Highlight</div>
<div><span class="label">title</span> 50% off food</div>
<div><span class="label">description</span> Test description</div>
<div><span class="label">code</span> 1524521</div>
<div><span class="label">popup_image</span> 4548</div>
<div><span class="label">popup_description</span> Popup description</div>
<div><span class="label">redirect_to</span> </div>

Or if you want to access 1 value directly.

$aCoupon = GetSettings::getPostMeta($post->ID, 'coupon');
$aCoupon = maybe_unserialze( $aCoupon );
if ( empty( $aCoupon ) ){
    //If the title is set, and is not empty, output it.
    if ( isset( $aCoupon['title'] ) && '' !== $aCoupon['title'] ) {
        echo '<div><span class="label">Title</span> ' . $aCoupon['title'] . '</div>';
    }
}

EDIT by @Shaun21uk - I got it to work making some minor changes (full code below). For whatever reason the $aCoupon = GetSettings::getPostMeta($coupon_id, 'coupon'); was breaking the function - I still would like to know how to tap into the theme's way of handling data.

Your shortcode function should look something like this:

add_shortcode( 'qg_shortcode', 'qg_shortcode' );
function qg_shortcode() {

    $q = new WP_Query(array(
        'post_type' => 'listing',
        'posts_per_page' => 5,
        'meta_key' => 'wc_coupon',
        'meta_value' => ' ',
        'meta_compare' => '!='
    ));

    if ( $q->have_posts() ) :
        while ( $q->have_posts() ) : $q->the_post();

            echo '<h2 class="text-center"><a href="' . get_permalink() . '">';
                the_title();
            echo '</a></h2>';

            the_content();

            // Get the ID of the attached coupon.
            $coupon_id = get_post_meta( get_the_ID(), 'wc_coupon', true );

            // Get the coupon details from the coupon using the coupons ID.
        $aCoupon = maybe_unserialize( $coupon_id );

            // This checks if the coupon details are NOT empty, if that is true, then output the info.
            if ( ! empty( $aCoupon ) ) {

                // If the title is set, and is not empty, output it.
                if ( isset( $aCoupon['title'] ) && '' !== $aCoupon['title'] ) {
                    echo '<div><span class="label">Title</span> ' . $aCoupon['title'] . '</div>';
                }
            }

            echo'<div class="offer-button">';
            echo'<a href="' . get_permalink() . '" class="offer-button-text">Claim this offer!</a>';
            echo'</div>';
        endwhile;
        wp_reset_postdata();
    endif;
}

@Shaun21uk 2019-05-13 21:05:19

Warwick, I couldn't fit my response in a comment so had to post my response as an answer. Sorry if that is wrong but I am new to the site and couldn't see another way.

@Warwick 2019-05-13 21:55:16

@Shaun21uk you should rather edit the original question and update that, instead of adding an answer. ;-)

@Warwick 2019-05-13 22:09:34

@Shaun21uk have a look at my answer now, I have added in a modified function to the bottom, which will hopefully have fixed your issue.

@Warwick 2019-05-13 22:12:58

@Shaun21uk, I have updated it again, I had to switch the wc_coupon and coupon around.

@Shaun21uk 2019-05-13 22:17:46

The output is still not looping any more and only printing the the_title and the_content. Seems the loop is broken somewhere and not even processing the [coupon] code?

@Shaun21uk 2019-05-13 22:28:40

As a side note, when I remove the code from $aCoupon to echo offer-button, the page loops the_title, the_content and the button correctly.

@Shaun21uk 2019-05-14 05:35:07

Thanks @Warwick - a little adjustment to your code above (I made the edit) and it is now working, don't think I ever would have got there without your help pal!

@Shaun21uk 2019-05-13 21:04:27

Warwick, thank you so much for taking the time to go through this.

My full code now looks like this:

add_shortcode( 'qg_shortcode', 'qg_shortcode' );
function qg_shortcode() {

    $q = new WP_Query(array(
        'post_type' => 'listing',
        'posts_per_page' => 5,
        'meta_key' => 'wc_coupon',
        'meta_value' => ' ',
        'meta_compare' => '!='
    ));
    if ( $q->have_posts() ) :
        while ( $q->have_posts() ) : $q->the_post();

            echo '<h2 class="text-center"><a href="' . get_permalink() . '">';
                the_title();
            echo '</a></h2>';

            the_content();

            $aCoupon = GetSettings::getPostMeta( get_the_ID(), 'wc_coupon');
            $aCoupon = maybe_unserialze( $aCoupon );

            if ( ! empty( $aCoupon ) ){
                //If the title is set, and is not empty, output it.
                if ( isset( $aCoupon['title'] ) && '' !== $aCoupon['title'] ) {
                    echo '<div><span class="label">Title</span> ' . $aCoupon['title'] . '</div>';
                }
            }

            echo'<div class="offer-button">';
            echo'<a href="' . get_permalink() . '" class="offer-button-text">Claim this offer!</a>';
            echo'</div>';
        endwhile;
        wp_reset_postdata();
    endif;
}
  • This is now only outputting one post and doesn't seem to be looping. Before I added your code it successfully displayed the title and link for two (all) posts containing a coupon. The one item it is displaying does indeed have a coupon though.
  • Your code is still not outputting the $aCoupon['title'], it's just blank.
  • It's worth mentioning that the meta_key for some reason is 'wc_coupon' which is why I use it in the wp_query filter, yet in the coupon.php code as shown, they clearly use just 'coupon'.

I really thought you had cracked it here! Perhaps I have the code set up wrong somewhere above as I am pretty new to php but trying to learn :)

@Warwick 2019-05-13 22:02:21

w.r.t "outputting one post". Does the offer button for the first post show? If not there could be an error in the code stopping it from looping.

@Warwick 2019-05-13 22:04:21

w.r.t "not outputting the $aCoupon['title']". The if statement, that checks for a title was set incorrectly. It should have had a ! in it. e.g ! empty( $aCoupon )

@Shaun21uk 2019-05-13 22:05:18

Actually no, the button isn't showing....I didn't spot that

@Warwick 2019-05-13 22:07:01

Lastly, the "coupons" ID is stored on the post in a custom field called wc_coupon. Once we have that ID, we can call the custom field coupon using the coupons ID to get the correct info. Basically the post just stores the ID of the coupon its linking to. We need to get the info from there.

Related Questions

Sponsored Content

1 Answered Questions

[SOLVED] Meta query with JSON value

1 Answered Questions

[SOLVED] Advanced WP Query hogs the SQL server

1 Answered Questions

1 Answered Questions

WP_Query about meta_key and its array value

  • 2017-12-13 04:05:27
  • JJang
  • 214 View
  • 0 Score
  • 1 Answer
  • Tags:   wp-query query

1 Answered Questions

[SOLVED] Custom WP Query from meta_value stored as serialised array

  • 2012-03-30 10:48:43
  • James Morrison
  • 941 View
  • 2 Score
  • 1 Answer
  • Tags:   wp-query meta-value

1 Answered Questions

[SOLVED] Saving custom fields for WP_Query to retrieve

1 Answered Questions

[SOLVED] new WP_Query to get max price meta value not working

1 Answered Questions

[SOLVED] Querying by meta key and value

  • 2014-11-09 09:47:00
  • Dongsan
  • 100 View
  • 0 Score
  • 1 Answer
  • Tags:   meta-query

0 Answered Questions

Orderby Meta Value and Query from Meta Query

1 Answered Questions

[SOLVED] Meta query with timestamp using WP_query

Sponsored Content