Custom fields from calculator plugin
-
Hi,
I use Stylemix’s Cost Calculator Builder plugin so customers can calculate and order custom products.
Obviously, I also use PDF Invoices & Packing Slips for WooCommerce and I’d like the details (length, width, height, etc.) of a custom item to be displayed on invoices and packing slips, just like they are on the shopping cart page.
I tried adding the following code to a custom template-functions file, without success:
add_action( 'wpo_wcpdf_after_item_meta', 'wpo_wcpdf_product_custom_field', 10, 3 );
function wpo_wcpdf_product_custom_field ( $template_type, $item, $order ) {
// check if product exists first
if (empty($item['product'])) return;
$field_name = 'meta_data[ccb_calculator]';
$details = $item['product']->get_meta($field_name,true,'edit');
if (!empty($details)) {
echo '<div class="product-details">Details: '.$details.'</div>';
}
}I also tried using subfields of the calculator (e.g., [quantity_field_id_0] for length). That didn’t work either.
Is the code incorrect or is it impossible to display these custom metadatas in invoices/packing slips ?
-
Hey @alexinwp,
My very first thought is that this line seems odd to me:
$field_name = 'meta_data[ccb_calculator]';I do not think that is correct custom field usage. I would expect this instead:
$field_name = 'ccb_calculator';Could you replace the line I mentioned and retry?
If that does not work, I recommend making sure that the custom field name you are using (ccb_calculator) is correct by following our documentation here:
Finding WooCommerce Custom Fields – WP Overnight documentation
This will help you either:
– Find the correct custom field name.
– Find the correct custom field structure (it could be embedded in another custom field).I myself am doubting that “ccb_calculator” is the name of the custom field you want to use, upon scanning the plugin code (but I could be wrong).
Please share your findings, they will help us all. π
Hey Darren,
Thanks for your reply. It seemed odd to me too (that’s what Store Toolkit displays though), but it didn’t work without the brackets either.
Now it does “work” if I put
if (empty($item['item'])) return;instead ofif (empty($item['product'])) return;on the previous line.This way, it displays “Details: Array” below the product.
According to Store Toolkit, [ccb_calculator] is an array of four items, including [calc_data], which is an array storing each customization option for my products (with another array containing individual labels and values). This is structured as follows :
ccb_calculator
| calc_data
| quantity_field_id_0
| label
| value
| quantity_field_id_1
| label
| valueThis is the tricky part for me because I don’t really know PHP.
How can I display my customization options (label + value) within a “Details” list ?
Thank you in advance !
Now it does βworkβ if I put
if (empty($item['item'])) return;instead ofif (empty($item['product'])) return;on the previous line.
I believe the reason your change returned some data is because you need to fetch the meta data of the woocommerce order item object (WC_Order_Item) instead of the meta data of the woocommerce product object (WC_Order_Item_Product). Your custom data would be attached to the order item in this case.—
I am still convinced that
ccb_calculatoris the correct field name, instead ofmeta_data[ccb_calculator]. I am not so sure why the Store Toolkit plugin displays it like that, but it has lead me to making the same mistake in the past. Supposedly, it is because the Store Toolkit plugin is showing the “data path” instead of the name of the woocommerce custom field.We likely need to update the documentation to address that.
Since
ccb_calculatoris an array, you need to loop through the array to reach the data you want. The looping is done by theforeachpart in the code below.—
Give this snippet a try:
add_action( 'wpo_wcpdf_after_item_meta', 'wpo_wcpdf_ccb_calculator_details', 10, 3 );
function wpo_wcpdf_ccb_calculator_details( $template_type, $item, $order ) {
if ( ! $item instanceof WC_Order_Item ) {
return;
}
$ccb_calculator = $item->get_meta( 'ccb_calculator', true, 'edit' );
if (
! is_array( $ccb_calculator )
|| empty( $ccb_calculator['calc_data'] )
|| ! is_array( $ccb_calculator['calc_data'] )
) {
return;
}
echo '<div class="product-details">';
echo '<strong>Details:</strong>';
echo '<ul>';
foreach ( $ccb_calculator['calc_data'] as $option ) {
$label = $option['label'] ?? '';
$value = $option['value'] ?? '';
if ( $label === '' && $value === '' ) {
continue;
}
echo '<li>';
echo esc_html( $label );
if ( $label !== '' && $value !== '' ) {
echo ': ';
}
echo esc_html( $value );
echo '</li>';
}
echo '</ul>';
echo '</div>';
}Disclaimer: I have not tested this code myself.
I am convinced it should work though.Hey @alexinwp,
Were you able to solve your issue with the last shared code snippet?
Hey Darren,
Sorry for the late reply, I’ve been busy with other things and haven’t had time to test it.
Thanks for the snippet and explanation. Unfortunately, it doesn’t work… Nothing else is displayed.
@alexinwp that’s unfortunate, sorry. π
I think I found my error however (or at least 1 error). In this block of code:
if ( ! $item instanceof WC_Order_Item ) {
return;
}I believe I’m supposed to use
$item['item']instead of just$item. A previous code adjustment you made (here) should even confirm this. So it is supposed to be:if ( ! $item['item'] instanceof WC_Order_Item ) {
return;
}So try this code snippet instead:
add_action( 'wpo_wcpdf_after_item_meta', 'wpo_wcpdf_ccb_calculator_details', 10, 3 );
function wpo_wcpdf_ccb_calculator_details( $template_type, $item, $order ) {
if ( ! $item['item'] instanceof WC_Order_Item ) {
return;
}
$ccb_calculator = $item->get_meta( 'ccb_calculator', true, 'edit' );
if (
! is_array( $ccb_calculator )
|| empty( $ccb_calculator['calc_data'] )
|| ! is_array( $ccb_calculator['calc_data'] )
) {
return;
}
echo '<div class="product-details">';
echo '<strong>Details:</strong>';
echo '<ul>';
foreach ( $ccb_calculator['calc_data'] as $option ) {
$label = $option['label'] ?? '';
$value = $option['value'] ?? '';
if ( $label === '' && $value === '' ) {
continue;
}
echo '<li>';
echo esc_html( $label );
if ( $label !== '' && $value !== '' ) {
echo ': ';
}
echo esc_html( $value );
echo '</li>';
}
echo '</ul>';
echo '</div>';
}If the correction above does not work, here are my troubleshooting steps…
- Could you tell me how much info is being displayed?
For example: Does the text “Details:” appear?
This helps me find the conditions I entered in the code snippet that is failing.
- Under this line of code:
$ccb_calculator = $item->get_meta( 'ccb_calculator', true, 'edit' );Could you add this?
var_dump( $ccb_calculator );Save the snippet, then check the PDF output to see if something gets printed and what the printed value is.
No problem mate.
The first correction got me a parse error message. The second one does nothing.
Could this be because we’re not explicitly naming each option contained in
calc_datathat we want to display ?Could this be because weβre not explicitly naming each option contained in
I am not quite sure of that. The “Details:” text is outside and before the calc_data loop. Since the “Details:” text is not even visible, then I am more immediately inclined to think one of these two conditions is failing.calc_datathat we want to display ?if ( ! $item['item'] instanceof WC_Order_Item ) {
return;
}OR
if (
! is_array( $ccb_calculator )
|| empty( $ccb_calculator['calc_data'] )
|| ! is_array( $ccb_calculator['calc_data'] )
) {
return;
}Hopefully this is not too advanced/complex:
Were you able to perform this troubleshooting step? I forgot to add one step at the end:
- Under this line of code:
$ccb_calculator = $item->get_meta( 'ccb_calculator', true, 'edit' );Could you add this?
var_dump( 'The custom field: ', $ccb_calculator );Finally, temporarily output your PDF as HTML in order to see the result of the
var_dump( $ccb_calculator )function.Path: WooCommerce > PDF Invoices > Advanced > Settings > Output to HTML.

The data you would be looking for is anything that appears after the “The custom field: ” text.
If there is no result at all, no printed text from the snippet in the item meta data area, then the 1st condition may be the condition that is failing. If “The custom field: ” text appears, then the 1st condition is not failing.
So there’s no printed text when I do it, but a “Fatal error: Call to a member function get_meta() on array” on the HTML output.
I also tried
$ccb_calculator = $item['item']->get_meta( 'ccb_calculator', true, 'edit' );instead of$ccb_calculator = $item->get_meta( 'ccb_calculator', true, 'edit' );.It removes all the order details (items, quantities, prices and totals) on the settings preview mode. On the HTML output though, all the details are here, I also got a big mess of arrays, labels, values and calculations AND my details list correctly displayed as expected.
I’m not sure if it’s worth mentioning, but the big mess of data includes the first options in the
ccb_calculatorarray :product_id,item_nameandorder_id, before thecalc_dataarray which contains the interesting options. It starts like that :array(6) { ["product_id"]=> int(34) ["item_name"]=> string(0) "" ["order_id"]=> int(0) ["calc_data"]=> array(14) { ["quantity_field_id_0"]=> array(2) { ["label"]=> string(12) "Longueur (L)" ["value"]=> string(6) "630 mm" }Your
$itemto$item['item']correction helped a lot. The diagnostic step was successful thanks to that. We will not need HTML mode anymore. πThe fact that you got a big mess of the data printed after the correction means that the 2nd condition was what was failing, as I had missed another incorrect usage of
$item, on this line:$ccb_calculator = $item->get_meta( 'ccb_calculator', true, 'edit' );This caused a fatal error because I was applying the
get_meta()function on the$itemarray object. We want that function on the WooCommerce order item object, so on$item['item'].This is the updated code snippet, with the above correction applied. I removed the
var_dump()function, so you should not get an ugly printed mess anymore and the table items will return:add_action( 'wpo_wcpdf_after_item_meta', 'wpo_wcpdf_ccb_calculator_details', 10, 3 );
function wpo_wcpdf_ccb_calculator_details( $template_type, $item, $order ) {
if ( ! $item['item'] instanceof WC_Order_Item ) {
return;
}
$ccb_calculator = $item['item']->get_meta( 'ccb_calculator', true, 'edit' );
if (
! is_array( $ccb_calculator )
|| empty( $ccb_calculator['calc_data'] )
|| ! is_array( $ccb_calculator['calc_data'] )
) {
return;
}
echo '<div class="product-details">';
echo '<strong>Details:</strong>';
echo '<ul>';
foreach ( $ccb_calculator['calc_data'] as $option ) {
$label = $option['label'] ?? '';
$value = $option['value'] ?? '';
if ( $label === '' && $value === '' ) {
continue;
}
echo '<li>';
echo esc_html( $label );
if ( $label !== '' && $value !== '' ) {
echo ': ';
}
echo esc_html( $value );
echo '</li>';
}
echo '</ul>';
echo '</div>';
}-
This reply was modified 3 weeks, 1 day ago by
Darren Peyou. Reason: additional info
Your
$itemto$item['item']correction helped a lot. The diagnostic step was successful thanks to that.I’m glad I did something… π
Thank you so much for your help and your time, it works perfectly now.
Take care.
- Could you tell me how much info is being displayed?
You must be logged in to reply to this topic.