WooCommerce – přidání polí do detailu produktu

Web autonalepky.cz, který prodává nálepky na auta, potřeboval vytvořit specifickou funkcionalitu – při importu produktů zjistit velikost obrázku ve formátu svg, uložit poměr stran, v detailu produktu pak zobrazovat přesné rozměry nálepek dle poměru stran, a dle toho počítat cenu.

Taková funkcionalita by samozřejmě šla zařídit variantami produktů, ale vzhledem k počtu produktů na eshopu (více než 3500) a množství variací (5 velikostí pro každý produkt) jsem se rozhodl pro programování na míru.

Jedním z kroků pro tuto funkcionalitu je zobrazování custom polí v detailu produktu. Něco podobného je poměrně častý požadavek, a níže je pro inspiraci kód, který to zařídí.
Kód postupně přidá pole k detailu produktu, uloží extra data do WooCommerce session, zobrazí je v košíku a pokladně, a uloží je jako metadata k jednotlivým položkám.

Hodnoty, které zákazník vybral, se pak automaticky zobrazují v administrace, všech emailech atd.

Jak to funnguje v praxi se můžete podívat na webu autonalepky.cz

[php]

<?php

namespace Autonalepky;

class WooCommerce {
function __construct() {
}

function initialize() {
add_action( ‘woocommerce_before_add_to_cart_button’, array( $this, ‘product_details’ ) );
add_filter( ‘woocommerce_add_cart_item_data’, array( $this, ‘add_custom_cart_item_data’ ), 10, 3 );
add_action( ‘woocommerce_add_order_item_meta’, array( $this, ‘add_order_item_meta’ ), 10, 2 );
add_filter( ‘woocommerce_get_item_data’, array( $this, ‘get_custom_cart_item_data’ ), 10, 2 );
}

/**
* Display the custom product details
*/
function product_details() {
/** @var $product \WC_Product */
global $product;

$sizes = $this->get_product_sizes( $product->get_id() );
$variants = $this->get_variants( $product->get_id() );

?>

<div>
<?php if ( in_array( ‘1’, $variants ) ): ?>
<p>
<label for="size"><?php _e( ‘Size’, AN_TEXTDOMAIN ); ?></label>
<select name="size" id="size" required="required">
<?php foreach ( $sizes as $size ) { ?>,
<option value="<?php echo $size[‘width’] . ‘x’ . $size[‘height’]; ?>"><?php echo str_replace( ‘.’, ‘,’, $size[‘width’] ) . ‘ x ‘ . str_replace( ‘.’, ‘,’, $size[‘height’] ); ?> cm</option>
<?php } ?>
</select>

</p>
<?php endif; ?>
<?php if ( in_array( ‘2’, $variants ) ): ?>
<p>
<label for="color"><?php _e( ‘Color’, AN_TEXTDOMAIN ); ?></label>
<select name="color" id="color" required="required">
<?php foreach ( $this->get_colors() as $color ) { ?>
<option value="<?php echo $color[‘id’]; ?>" data-color="<?php echo $color[‘color’]; ?>"><?php echo $color[‘name’]; ?></option>
<?php } ?>
</select>
</p>
<?php else: ?>
<input type="hidden" name="color" value="as-is">
<?php endif; ?>
<?php if ( in_array( ‘3’, $variants ) ): ?>
<p>
<label for="inverse"><?php _e( ‘Inverse’, AN_TEXTDOMAIN ); ?></label>
<select name="inverse" id="inverse">
<option value="none"><?php _e( ‘As is’, AN_TEXTDOMAIN ); ?></option>
<option value="horizontally"><?php _e( ‘Flip horizontally’, AN_TEXTDOMAIN ); ?></option>

</select>
</p>
<?php endif; ?>
<input type="hidden" name="product_id" value="<?php echo $product->get_id(); ?>"/>

</div>
<?php }

/**
* Save the cart item data to the session
*
* @param $cart_item_data
* @param $product_id
* @param $variation_id
*
* @return mixed
*/
function add_custom_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
$cart_item_data[‘size’] = filter_input( INPUT_POST, ‘size’ );;
$cart_item_data[‘color’] = filter_input( INPUT_POST, ‘color’ );
$cart_item_data[‘inverse’] = filter_input( INPUT_POST, ‘inverse’ );;

return $cart_item_data;
}

/**
* Display the cart item data on cart and checkout
*
* @param $item_data
* @param $cart_item
*
* @return array
*/
function get_custom_cart_item_data( $item_data, $cart_item ) {
$item_data[] = array(
‘key’ => __( ‘Color’, AN_TEXTDOMAIN ),
‘value’ => wc_clean( $cart_item[‘color’] ),
‘display’ => $cart_item[‘color’]
);

$item_data[] = array(
‘key’ => __( ‘Size’, AN_TEXTDOMAIN ),
‘value’ => wc_clean( $cart_item[‘size’] ),
‘display’ => wc_clean( $cart_item[‘size’] ),
);

$item_data[] = array(
‘key’ => __( ‘Inverse’, AN_TEXTDOMAIN ),
‘value’ => wc_clean( $cart_item[‘inverse’] ),
‘display’ => wc_clean( $cart_item[‘inverse’] )
);

return $item_data;
}

/**
* Save the extra data to the item
* @param $item_id
* @param $values
*/
function add_order_item_meta( $item_id, $values ) {
$wc = new WooCommerce();
$colors = $wc->get_colors();

$inverse = $values[‘inverse’] == ‘none’ ? __( "Don’t inverse", AN_TEXTDOMAIN ) : __( "Flip horizontally", AN_TEXTDOMAIN );
wc_add_order_item_meta( $item_id, __( ‘Color’, AN_TEXTDOMAIN ), $colors[ $values[‘color’] ][‘name’] );
wc_add_order_item_meta( $item_id, __( ‘Size’, AN_TEXTDOMAIN ), $values[‘size’] );
wc_add_order_item_meta( $item_id, __( ‘Inverse’, AN_TEXTDOMAIN ), $inverse );
}
}

$WooCommerce = new WooCommerce();
$WooCommerce->initialize();

[/php]

 

1 Comment

  1. Robert Šperka - Autonálepky.cz on 13.9.2018 at 23:34

    Dlouhou dobu jsem hledal programátora, který by dokázal vytvořit e-shop dle mých představ za rozumných logických podmínek. Věděl jsem přesně co chci a jak to chci udělat. Nevěřil jsem, že na Woocommerce to dokážeme. Václav Greif, byl jediný, který pochopil mou problematiku a zároveň jednoduchost řešení. Díky němu jsem dosáhl optimálního výsledku, který jsem si představoval. A funguje to 😉 Mohu jen doporučit. Dokáže se vžít do problematiky a logicky ji řešit.

Přidat komentář