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]
Václav Greif se programování pro Wordpress věnuje více než 16 let. Za tu dobu nasbíral mnoho zkušeností s tvorbou pluginů pro Wordpress, úpravou šablon a programováním komplexních funkcionalit. Věnuje se programování pro Wordpress a školení programátorů.

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.