Ask your WordPress questions! Pay money and get answers fast! (more info)

Extracting values from a serialized array WordPress

  • SOLVED

Hi there, I am attempting to unserialize a Woocommerce shop order array. An example array is shown below:


a:2:{i:0;a:10:{s:2:"id";s:3:"466";s:12:"variation_id";s:0:"";s:4:"name";s:19:"First Aid course";s:3:"qty";s:1:"1";s:9:"item_meta";a:0:{}s:13:"line_subtotal";s:2:"45";s:17:"line_subtotal_tax";s:1:"0";s:10:"line_total";s:2:"45";s:8:"line_tax";s:1:"0";s:9:"tax_class";s:0:"";}i:1;a:10:{s:2:"id";s:3:"412";s:12:"variation_id";s:3:"434";s:4:"name";s:34:"Gym membership";s:3:"qty";s:1:"1";s:9:"item_meta";a:3:{i:0;a:2:{s:9:"meta_name";s:22:"pa_membership-category";s:10:"meta_value";s:7:"public";}i:1;a:2:{s:9:"meta_name";s:18:"pa_membership-type";s:10:"meta_value";s:5:"combo";}i:2;a:2:{s:9:"meta_name";s:18:"pa_membership-term";s:10:"meta_value";s:8:"6-months";}}s:13:"line_subtotal";s:3:"180";s:17:"line_subtotal_tax";s:1:"0";s:10:"line_total";s:3:"180";s:8:"line_tax";s:1:"0";s:9:"tax_class";s:0:"";}}


I need to extract and print each product 'name' value (the '_order_items' meta array can contain multiple product names - the example above shows two product names).

The code I have so far is shown below:


<?php
$member_email = get_post_meta($post->ID, 'ecpt_member_email', true);
$args = array( 'post_type' => 'shop_order', 'meta_key' => '_billing_email', 'meta_value' => $member_email, 'posts_per_page' => 10 );
$loop = new WP_Query( $args ); ?>
<?php if ( $loop->have_posts() ) : ?>
<div class="member-payments">
<h2>Payments (online)</h2>
<ul>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php $order_total = get_post_meta($post->ID, '_order_total', true); ?>
<?php $order_items = get_post_meta($post->ID, '_order_items', true); ?>
<?php $order_items = unserialize($order_items); ?>
<li><?php echo get_the_date(); ?> - <?php echo $order_items['name'][0]; ?> - <?php echo $order_total; ?> - <?php edit_post_link('Edit', '(', ')'); ?></li>
<?php endwhile; ?>
</ul>
</div>
<?php endif; ?>
<?php wp_reset_query(); ?>


Please can someone re-write the <?php echo $order_items['name'][0]; ?> segment with some sort of foreach loop that successfully prints the 'name' of each product in the order array.

Thank you

Answers (3)

2012-08-29

Gabriel Reguly answers:

Hi,

Why not use the WooCommerce code for it?


if (sizeof($order->get_items())>0) :

foreach($order->get_items() as $item) :

if (isset($item['variation_id']) && $item['variation_id'] > 0) :
$_product = new WC_Product_Variation( $item['variation_id'] );
else :
$_product = new WC_Product( $item['id'] );
endif;

echo '
<tr class = "' . esc_attr( apply_filters('woocommerce_order_table_item_class', 'order_table_item', $item, $order ) ) . '">
<td class="product-name">';

echo '<a href="'.get_permalink( $item['id'] ).'">' . $item['name'] . '</a>';

$item_meta = new order_item_meta( $item['item_meta'] );
$item_meta->display();

if ( $_product->exists() && $_product->is_downloadable() && $_product->has_file() && ( $order->status=='completed' || ( get_option( 'woocommerce_downloads_grant_access_after_payment' ) == 'yes' && $order->status == 'processing' ) ) ) :

echo '<br/><small><a href="' . $order->get_downloadable_file_url( $item['id'], $item['variation_id'] ) . '">' . __('Download file &rarr;', 'woocommerce') . '</a></small>';

endif;

echo '</td><td class="product-quantity">'.$item['qty'].'</td><td class="product-total">' . $order->get_formatted_line_subtotal($item) . '</td></tr>';

// Show any purchase notes
if ($order->status=='completed' || $order->status=='processing') :
if ($purchase_note = get_post_meta( $_product->id, '_purchase_note', true)) :
echo '<tr class="product-purchase-note"><td colspan="3">' . apply_filters('the_content', $purchase_note) . '</td></tr>';
endif;
endif;

endforeach;
endif;



Regards,
Gabriel


Gabriel Reguly comments:

Code would be like this


<?php

$member_email = get_post_meta($post->ID, 'ecpt_member_email', true);

$args = array( 'post_type' => 'shop_order', 'meta_key' => '_billing_email', 'meta_value' => $member_email, 'posts_per_page' => 10 );

$loop = new WP_Query( $args ); ?>

<?php if ( $loop->have_posts() ) : ?>

<div class="member-payments">

<h2>Payments (online)</h2>

<ul>

<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>

<?php $order_total = get_post_meta($post->ID, '_order_total', true); ?>

<?php $order_items = get_post_meta($post->ID, '_order_items', true); ?>

<li><?php echo get_the_date(); ?> -

$order = new WC_Order( $$post->ID );
if (sizeof($order->get_items())>0) {
foreach($order->get_items() as $item) {
echo $item['name'];
}
}


- <?php echo $order_total; ?> - <?php edit_post_link('Edit', '(', ')'); ?></li>

<?php endwhile; ?>

</ul>

</div>

<?php endif; ?>

<?php wp_reset_query(); ?>


designbuildtest comments:

Thanks Gabriel. I simply need the product name(s). If you can streamline the above Woo code and incorporate this new lightweight snippet into my existing code segment (shown in original question above) that would work I guess. Thanks.


Gabriel Reguly comments:

I have just done it, please see above.


Gabriel Reguly comments:

Oh dears, there is some extra $ in this code

$order = new WC_Order( $$post->ID );

please remove the extra $

$order = new WC_Order( $post->ID );

(Sometimes quick answers result in silly errors....)


designbuildtest comments:

Perfect! Many thanks Gabriel. With your method, is it easy to extract the product variation values? If so, how would the code look if product variations were also added? Thanks again.


Gabriel Reguly comments:

Well, the WooCommerce code do has something for variations.

By chance, are you looking for the donwload links?

Please add this code (first line is just reference)


foreach($order->get_items() as $item) {
if (isset($item['variation_id']) && $item['variation_id'] > 0) :
$_product = new WC_Product_Variation( $item['variation_id'] );
else :
$_product = new WC_Product( $item['id'] );
endif;
if ( $_product->exists() && $_product->is_downloadable() && $_product->has_file() && ( $order->status=='completed' || ( get_option( 'woocommerce_downloads_grant_access_after_payment' ) == 'yes' && $order->status == 'processing' ) ) ) :

echo '<br/><small><a href="' . $order->get_downloadable_file_url( $item['id'], $item['variation_id'] ) . '">' . __('Download file &rarr;', 'woocommerce') . '</a></small>';

endif;


Would you mind adding a bit more to the prize as the question has been extended?


designbuildtest comments:

Hi Gabriel, absolutely, I don't mind adding another $5 to the prize, but please can you re-write my code to integrate the Woo product variations snippet (I've tried myself, but can't figure it out). My code currently looks like this:


<?php
$member_email = get_post_meta($post->ID, 'ecpt_member_email', true);
$args = array( 'post_type' => 'shop_order', 'meta_key' => '_billing_email', 'meta_value' => $member_email, 'posts_per_page' => 10 );
$loop = new WP_Query( $args ); ?>
<?php if ( $loop->have_posts() ) : ?>
<div class="member-payments">
<h2>Payments (online)</h2>
<ul>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php $order_total = get_post_meta($post->ID, '_order_total', true); ?>
<li>
<?php echo get_the_date(); ?> -
<?php
$order = new WC_Order( $post->ID );
if (sizeof($order->get_items())>0) {
foreach($order->get_items() as $item) {
echo $item['name']; // Variations should appear after the product name
}
}
?> -
<?php echo $order_total; ?> -
<?php edit_post_link('Edit', '(', ')'); ?>
</li>
<?php endwhile; ?>
</ul>
</div>
<?php endif; ?>
<?php wp_reset_query(); ?>


We are not selling downloadable products, but the products are virtual (i.e. memberships and subscriptions)

Thanks


Gabriel Reguly comments:

Ok, please bear with me.


Gabriel Reguly comments:

Here you have it


<?php
$member_email = get_post_meta($post->ID, 'ecpt_member_email', true);
$args = array( 'post_type' => 'shop_order', 'meta_key' => '_billing_email', 'meta_value' => $member_email, 'posts_per_page' => 10 );
$loop = new WP_Query( $args ); ?>
<?php if ( $loop->have_posts() ) : ?>
<div class="member-payments">
<h2>Payments (online)</h2>
<ul>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php $order_total = get_post_meta($post->ID, '_order_total', true); ?>
<li>
<?php echo get_the_date(); ?> -
<?php
$order = new WC_Order( $post->ID );
if (sizeof($order->get_items())>0) {
foreach($order->get_items() as $item) {
echo $item['name']; // Variations should appear after the product name
$item_meta = new order_item_meta( $item['item_meta'] );
$item_meta->display();
}
}
?> -
<?php echo $order_total; ?> -
<?php edit_post_link('Edit', '(', ')'); ?>
</li>
<?php endwhile; ?>
</ul>
</div>
<?php endif; ?>
<?php wp_reset_query(); ?>


Hope that is what you expected.

Another extension, another $5 perhaps? ;-)


designbuildtest comments:

Hi Gabriel, code doesn't work unfortunately.

If I'm correct, the only change you made to my code was the addition of the lines:

$item_meta = new order_item_meta( $item['item_meta'] );
$item_meta->display();


Does the item_meta have to be referenced/initiated elsewhere before

$item_meta->display();

is called?

Thanks.


Gabriel Reguly comments:

Hmm, are you sure you have the variations set? What does your order view page shows?

Anyway, yes, $item_meta is created here:

$item_meta = new order_item_meta( $item['item_meta'] );

and then displayed here:

$item_meta->display()


Gabriel Reguly comments:

To find your order view page, goto to

http://example.com/wp-admin/admin.php?page=woocommerce_status


Then the page you are looking for is the second bottom-up from Core Taxonomies

Ver página de pedidos #11 - http://example.com/?page_id=11
Página Alterar Senha #12 - http://example.com/?page_id=12
Core Taxonomies

Sorry, my setup uses Portuguese, but I think you can see what I mean.


Gabriel Reguly comments:

Of course you should replace example.com with your URL.

Also, my view order page is ?page=11 and yours most likely will be a different one.

I am going offline soon, it is past bedtime already.


designbuildtest comments:

Hi there, I'm pretty positive my variations have been set properly (see attached image for a screengrab).

In an earlier piece of code you had:


if (isset($item['variation_id']) && $item['variation_id'] > 0) :

$_product = new WC_Product_Variation( $item['variation_id'] );

else :

$_product = new WC_Product( $item['id'] );

endif;


This or a variation of this code does not appear anywhere in your revised solution.

Could this be part of the problem perhaps?