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ář