quasel
4/16/2017 - 9:22 AM

Include this in your theme to allow WooCommerce variable products to be displayed in a grid format with each variation having there own quan

Include this in your theme to allow WooCommerce variable products to be displayed in a grid format with each variation having there own quantity and add to cart button, rather then the drop-down options. This should be include in your themes function file.

<?php
/**
 * Woocommerce Custom Variation Output
 *
 * The following function allow for the theme to display product variations in a grid format.
 * This code could be moved to a plugin but is in the theme function file as it used the
 * themes grid system.
 *
 * @package WooGrid
 * @since WooGrid 1.2
 * @reference: http://www.eggplantstudios.ca/woocommerce-product-variation-add-cart-grid/
 */

/**
 * Add option to allow the variations to be displayed in a grid or default layout
 *
 * @since WooGrid 1.0
 */
function variation_grid_advanced_fields() {
	global $woocommerce, $post;
	echo '<div class="options_group show_if_variable">';
		$variation_grid_view = get_post_meta( $post->ID, 'variation_grid_view', true );
		woocommerce_wp_checkbox(
			array(
				'id' 			=> 'variation_grid_view',
				'wrapper_class' => 'show_if_variable',
				'label' 		=> __( 'Show Variations in Grid' ),
				'description' 	=> __( 'Enable' ),
				'cbvalue' 		=> true,
			)
		);
	echo '</div>';
}
add_action( 'woocommerce_product_options_general_product_data', 'variation_grid_advanced_fields' );

/**
 * Save option if the variation is in grid layout
 *
 * @param int $post_id the post id of the current product.
 *
 * @since WooGrid 1.0
 */
function variation_grid_advanced_fields_save( $post_id ) {
	// Save checkbox options.
	if ( ! empty( $_POST['variation_grid_view'] ) ) { // TODO: add nonce.
		update_post_meta( $post_id, 'variation_grid_view', true );
	} else {
		update_post_meta( $post_id, 'variation_grid_view', false );
	}
}
add_action( 'woocommerce_process_product_meta', 'variation_grid_advanced_fields_save' );


/**
 * Display in grid format by overwriting woocommerce template
 *
 * @since WooGrid 1.0
 */
function variation_grid_variable_add_to_cart() {
	global $product, $post, $woocommerce;

	$variations = find_valid_variations();
	$attributes = $product->get_attributes();

	// Check if the special 'variation_grid_view' meta is set to false, load the default template.
	if ( ! get_post_meta( $post->ID, 'variation_grid_view', true ) ) {

		// Enqueue variation scripts.
		wp_enqueue_script( 'wc-add-to-cart-variation' );

		// Load the template.
		wc_get_template( 'single-product/add-to-cart/variable.php', array(
				'available_variations'  => $product->get_available_variations(),
				'attributes'            => $product->get_variation_attributes(),
				'selected_attributes'   => $product->get_variation_default_attributes(),
		) );

		return;
	}

	?>

	<div class="variations variations-grid clearfix">

		<?php // Loop through visible variations.
		foreach ( $variations as $key => $value ) :

			if ( ! $value['variation_is_visible'] ) { continue;
			} ?>

			<div itemprop="offers" itemscope itemtype="http://schema.org/Offer" class="clearfix">

				<?php // Loop through and print the attribute names.
				$name_output = null;

				foreach ( $value['attributes'] as $key => $val ) {

					$key = str_replace( 'attribute_', '', $key ); // Clean the attribute name.

					$attribute = $attributes[ $key ]; // Get the attribute data.

					// Check for variation description first.
					if ( isset( $value['variation_description'] ) && ! empty( $value['variation_description'] ) ) {

							$description = wptexturize( strip_tags( $value['variation_description'] ) );
							$name_output[] = '<span class="variation-titles attr var-description">' . $description . '</span>';
							break; // Since there is a variation description set we can exit the loop.

					} else {

						// Check if the attribute is a taxonomy.
						if ( $attribute['is_taxonomy'] ) {

							// Get the taxonomy name.
							$attr_name = get_term_by( 'slug', $val, $key, 'ARRAY_A' );
							$attr_name = $attr_name['name'];

						} else {
							$attr_name = ucwords( $val ); // Clean up the custom attribute name.
						}

						$name_output[] = '<span class="variation-titles attr attr-' . $key . '">' . $attr_name . '</span>';

					}

					$i++;
				}
				?>

				<div class="variation-meta">

					<?php // Dump the output.
					echo implode( '', (array) $name_output );

					// Add sku if we have one.
					if ( ! empty( $value['sku'] ) ) {
						echo '<span class="sku">' . $value['sku'] . '</span>';
					}

					// Force the price to always print.
					if ( empty( $value['price_html'] ) ) {
						$price = '<span class="price">' . wc_price( $value['display_price'] ) . '</span>';
					} else {
						$price = $value['price_html'];
					}

					// Print the availability message.
					// echo $value['availability_html'];
					?>

					<?php // Make sure there is more than 1 variation.
					if ( count( $variations ) > 1 ) : ?>
					<span itemprop="price" class="variation-price"><?php echo $price; ?></span>
					<?php endif; ?>

					<?php
						$availability_html = $value['availability_html'];
					if ( ! empty( $availability_html ) && $value['backorders_allowed'] ) {
						echo apply_filters( 'woocommerce_stock_html', $availability_html );
					}
					?>

				</div>

				<?php if ( $value['is_in_stock'] ) : ?>

					<form class="cart" action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" method="post" enctype='multipart/form-data'>

						<?php if ( ! $product->is_sold_individually() ) : ?>
							<?php woocommerce_quantity_input( array( 'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : 1 ) ); ?>
						<?php endif; ?>

						<?php // Run through the attributes and print them in hidden inputs.
						if ( ! empty( $value['attributes'] ) ) {
							foreach ( $value['attributes'] as $attr_key => $attr_value ) { ?>

							<input type="hidden" name="<?php echo $attr_key?>" value="<?php echo $attr_value?>">

							<?php
							}
						} ?>

						<button type="submit" class="single_add_to_cart_button button alt">Add to cart</button>
						<input type="hidden" name="variation_id" value="<?php echo $value['variation_id']?>" />
						<input type="hidden" name="product_id" value="<?php echo esc_attr( $post->ID ); ?>" />
						<input type="hidden" name="add-to-cart" value="<?php echo esc_attr( $post->ID ); ?>" />

					</form>

				<?php else : // Out of Stock. ?>

					<div class="stock-message">
						<p class="stock out-of-stock"><?php _e( 'Out of Stock', 'woocommerce' ); ?></p>
					</div>

				<?php endif; ?>

			</div>

		<?php endforeach; ?>

	</div>

	<?php
}
add_action( 'woocommerce_variable-subscription_add_to_cart', 'variation_grid_variable_add_to_cart' );
remove_action( 'woocommerce_variable-subscription_add_to_cart', array( 'WC_Subscriptions', 'variable_subscription_add_to_cart' ), 30 );

/**
 * Collect all the variations of a product and add them in a new array to use for displaying them in the grid
 *
 * @since WooGrid 1.0
 */
function find_valid_variations() {
	global $product;

	$variations = $product->get_available_variations();
	$attributes = $product->get_attributes();
	$new_variants = array();

	// Loop through all variations
	foreach ( $variations as $variation ) {

		// Peruse the attributes.
		// 1. If both are explicitly set, this is a valid variation
		// 2. If one is not set, that means any, and we must 'create' the rest.
		$valid = true; // so far
		foreach ( $attributes as $slug => $args ) {

			if ( array_key_exists( "attribute_$slug", $variation['attributes'] ) && ! empty( $variation['attributes'][ "attribute_$slug" ] ) ) {
				// Exists
			} else {

				// Not exists, create.
				$valid = false; // it contains 'anys'.

				// loop through all options for the 'ANY' attribute, and add each.
				foreach ( explode( '|', $attributes[ $slug ]['value'] ) as $attribute ) {
					$attribute = trim( $attribute );
					$new_variant = $variation;
					$new_variant['attributes'][ "attribute_$slug" ] = $attribute;
					$new_variants[] = $new_variant;
				}
			}
		}

		// This contains ALL set attributes, and is itself a 'valid' variation.
		if ( $valid ) {
			$new_variants[] = $variation;
		}
	}

	return $new_variants;
}

/**
 * Custom Add To Cart Messages
 *
 * @param string $message the message to update.
 * @param int $product_id the post id of the current product.
 *
 * @since WooGrid 1.0
 */
function custom_add_to_cart_message( $message, $product_id ) {

	// Collect the variation if is exists.
	$variation_id = isset( $_REQUEST['variation_id'] ) ? $_REQUEST['variation_id'] : null;
	$name_output = array();

	if ( is_array( $product_id ) ) { // Multiple item added to cart - Grouped Product.

		$titles = array();

		foreach ( $product_id as $id ) {
			$titles[] = get_the_title( $id );
		}

		$added_text = sprintf( __( 'Added %s to your cart.', 'woocommerce' ), wc_format_list_of_items( $titles ) );

	} else { // One item added to cart.

		// Add variation name to the product title.
		$added_text = '';

		if ( ! empty( $variation_id ) ) {

			// Check for variation description first and use that if available.
			$description = get_post_meta( $variation_id, '_variation_description', true );
			if ( ! empty( $description ) ) {

				if ( ! in_array( $attr_name, $name_output ) ) {
					$name_output[] = strip_tags( $description );
				}
			} else {

				// Collect the product, product variations and attributes.
				$var_product = get_product( $variation_id );
				$variations = $var_product->get_variation_attributes();
				$attributes = $var_product->get_attributes();

				if ( is_array( $variations ) ) {

					foreach ( $variations as $key => $value ) {

						$key = str_replace( 'attribute_', '', $key ); // Clean the attribute name.

						$attribute = $attributes[ $key ]; // Get the attribute data.

						// Check if the attribute is a taxonomy.
						if ( $attribute['is_taxonomy'] ) {

							// Get the taxonomy name.
							$attr_name = get_term_by( 'slug', $value, $key, 'ARRAY_A' );
							$attr_name = $attr_name['name'];

						} else {
							$attr_name = ucwords( $value ); // Clean up the custom attribute name.
						}

						if ( ! in_array( $attr_name, $name_output ) ) {
							$name_output[] = $attr_name; // Load them into an array to be imploded.
						}
					}
				}
			}
		}

		$product_title = get_the_title( $product_id ); // Get the main product title.

		$product_title .= ( ! empty( $name_output ) ) ? ' &mdash; ' . implode( ', ', $name_output ) : ''; // Add variation(s) if not null.

		$added_text = sprintf( __( '&quot;%s&quot; was successfully added to your cart.', 'woocommerce' ), $product_title );
	}

	// Output success messages.
	if ( get_option( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) :

		$return_to 	= apply_filters( 'woocommerce_continue_shopping_redirect', wp_get_referer() ? wp_get_referer() : home_url() );

		$message 	= sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', $return_to, __( 'Continue Shopping', 'woocommerce' ), $added_text );

	else :

		$message 	= sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', wc_get_page_permalink( 'cart' ), __( 'View Cart', 'woocommerce' ), $added_text );

	endif;

	return $message;
}
add_filter( 'wc_add_to_cart_message', 'custom_add_to_cart_message', 10, 2 );