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.
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.
Share Improve this question edited May 14, 2019 at 8:54 norman.lol 3,2413 gold badges30 silver badges35 bronze badges asked May 13, 2019 at 18:19 Shaun21ukShaun21uk 311 silver badge8 bronze badges2 Answers
Reset to default 1The 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;
}
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 :)