Códigos Woocommerce para el functions.php de tu web

Bueno, ya hemos hablado de la importancia del archivo functions.php dentro de WordPress, podéis verlo aquí. Resumiendo un poco, nuestro archivo functions.php que podremos encontrar dentro de la raíz del directorio de nuestro tema utilizado, es el encargado entre otras cosas, de dotar de nuevas funcionalidades a nuestra web.

A continuación (iré añadiendo más y haré más posts para segmentar códigos según tipo de utilidades) os dejo algunos de los códigos para Woocommerce más utilizados en el functions de nuestro WordPress. Sólo tienes que copiar y pegar los códigos que veras a continuación en tu archivo functions.php.

Advertencia: Esta entrada contiene códigos o snippets que podrían no funcionar correctamente en tu instalación de WordPress, o podrían ser incompatibles con tu tema o plugins activos. ÚSALOS SIEMPRE BAJO TU RESPONSABILIDAD, preferiblemente en un entorno de desarrollo y haz siempre una copia de seguridad de tus archivos antes de modificarlos

Códigos Woocommerce para el functions.php

Códigos para la página de categorías de producto o páginas donde quieras mostrar productos

En la página de categorías de nuestros productos podemos hacer varios cambios desde nuestro functions.php si nuestro tema no nos lo permite. También vas a ver algunos sencillos Shortcodes de Woocommerce para añadir en cualquier lugar, post o página, los artículos que desees.

Código productos por página

Código ideal para mostrar el número de productos que deseamos ver en una página.

/*Productos por página*/
add_filter( 'loop_shop_per_page', 'especialistas_wordpress_productos_por_pagina', 20 ); //Elegir el número de productos por página
function especialistas_wordpress_productos_por_pagina($products_per_page) { return 1000; }
remove_action( 'woocommerce_before_shop_loop' , 'woocommerce_catalog_ordering', 30 ); // Quitamos la caja de ordenar
remove_action( 'woocommerce_before_shop_loop' , 'woocommerce_result_count', 20 ); // Quitamos el número de resutlados

Shortcodes para añadir en cualquier página

//Shortcode de Woocommerce para añadir productos con orden aleatório. Ideal para portadas de páginas donde quieres que se "vea" mucho contenido diferente. 
[recent_products columns="4" limit="8" orderby="rand"] //(en este caso está limitado a 4 columnas y 8 productos, luego aparecerán 2 filas de artículos. Hay que comprobar cómo tenemos la configuración de Woocommerce e intentar poner la misma cantidad de columnas en el shortcode que en la configuración, para que a la hora de mostrar los artículos no tengamos problemas de visualización.)

//Para añadir una categoría específica o varias habría que utilizar category="nombre-categoria" o category="nombre-categoria1, nombre categoria2" cat_operator="AND"(con el operador "AND" le indicamos que incluya las 2 categorías)
//Para añadir productos que NO estén en una categoría o varias específicas, el operador sería cat_operator="NOT IN".

//Shortcode para mostrar los productos más nuevos
[products limit="4" columns="4" orderby="id" order="DESC" visibility="visible"]

//Shortcode para mostrar los productos más vendidos
[products limit="4" columns="4" best_selling="true" ]

//Shortcode de productos destacados
[products limit="4" columns="4" visibility="featured" ]
PUEDES ACCEDER A TODOS LOS SHORTSCODES EN LA DOCUMENTACIÓN DE WOOCOMMERCE https://woocommerce.com/document/shortcodes-incluidos-en-woocommerce/

Códigos para mostrar precios «desde»

Este es uno de los códigos más complejos por las posibles variaciones y sinceramente no entiendo por qué no ha incluido de forma nativa ya Woocommerce el tema, pero bueno, aquí va…

//Precios desde
 function wc_wc20_variation_price_format( $price, $product ) {
    // Main Price
    $prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
    $price = $prices[0] !== $prices[1] ? sprintf( __( 'Desde: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

    // Sale Price
    $prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
    sort( $prices );
    $saleprice = $prices[0] !== $prices[1] ? sprintf( __( 'Desde: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

    if ( $price !== $saleprice ) {
        $price = '<del>' . $saleprice . '</del> <ins>' . $price . '</ins>';
    }
    
    return $price;
}
add_filter( 'woocommerce_variable_sale_price_html', 'wc_wc20_variation_price_format', 10, 2 );
add_filter( 'woocommerce_variable_price_html', 'wc_wc20_variation_price_format', 10, 2 );


// Función para obtener el precio de la variación por defecto (si existe)
function get_default_variation( $product ){
    $attributes_count = count($product->get_variation_attributes());
    $default_attributes = $product->get_default_attributes();
    // Si no hay variación por defecto salimos
    if( $attributes_count != count($default_attributes) )
        return false;

    // Loop por las variaciones disponibles
    foreach( $product->get_available_variations() as $variation ){
        $found = true;
        // Loop por los atributos de las variaciones
        foreach( $variation['attributes'] as $key => $value ){
            $taxonomy = str_replace( 'attribute_', '', $key );
            // Busqueda de una variación por defecto
            if( isset($default_attributes[$taxonomy]) && $default_attributes[$taxonomy] != $value ){
                $found = false;
                break;
            }
        }
        // Si tenemos variación por defecto
        if( $found ) {
            $default_variaton = $variation;
            break;
        }
        // Si no, continuamos
        else {
            continue;
        }
    }
    return isset($default_variaton) ? $default_variaton : false;
}

add_action( 'woocommerce_before_single_product', 'move_variations_single_price', 1 );
function move_variations_single_price(){
    global $product, $post;

    if ( $product->is_type( 'variable' ) ) {
        // quitando el precio de las variaciones en productos variables
        remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );

        // Cambiamos la ubicación y volvemos a insertar los precios de las variaciones
        add_action( 'woocommerce_single_product_summary', 'replace_variation_single_price', 10 );
    }
}

function replace_variation_single_price(){
    global $product;

    // Precio principal
    $prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
    $active_price = $prices[0] !== $prices[1] ? sprintf( __( 'Desde: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

    // Precio rebajado
    $prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
    sort( $prices );
    $regular_price = $prices[0] !== $prices[1] ? sprintf( __( 'Desde: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

    if ( $active_price !== $regular_price && $product->is_on_sale() ) {
        $price = '<del>' . $regular_price . $product->get_price_suffix() . '</del> <ins>' . $active_price . $product->get_price_suffix() . '</ins>';
    } else {
        $price = $regular_price;
    }

    // Cuando hay variación por defecto
    if( get_default_variation( $product ) ) {
        $default_variaton = get_default_variation( $product );
        if( ! empty($default_variaton['price_html']) ){
            $price_html = $default_variaton['price_html'];
        } else {
            if ( ! $product->is_on_sale() )
                $price_html = $price = wc_price($default_variaton['display_price']);
            else
                $price_html = $price;
        }
        $availiability = $default_variaton['availability_html'];
    } else {
        $price_html = $price;
        $availiability = '';
    }
    // Estilos para añadir en tu css de tu tema ?>
    <style>
        div.woocommerce-variation-price,
        div.woocommerce-variation-availability,
        div.hidden-variable-price {
            height: 0px !important;
            overflow:hidden;
            position:relative;
            line-height: 0px !important;
            font-size: 0% !important;
        }
    </style>
    <?php // Jquery ?>
    <script>
    jQuery(document).ready(function($) {
        var a = 'div.wc-availability', p = 'p.price';

        $('select').blur( function(){
            if( '' != $('input.variation_id').val() ){
                if($(a).html() != '' ) $(a).html('');
                $(p).html($('div.woocommerce-variation-price > span.price').html());
                $(a).html($('div.woocommerce-variation-availability').html());
            } else {
                if($(a).html() != '' ) $(a).html('');
                $(p).html($('div.hidden-variable-price').html());
            }
        });
    });
    </script>
    <?php

    echo '<p class="price">'.$price_html.'</p>
    <div class="wc-availability">'.$availiability.'</div>
    <div class="hidden-variable-price" >'.$price.'</div>';
}

//Precios desde con descuentos
function dcms_variation_price_format( $price, $product ) {

	$min_price = $product->get_variation_regular_price( 'min' );
	$max_price = $product->get_variation_regular_price( 'max' );
	$min_sale_price = $product->get_variation_sale_price( 'min' );
	$max_sale_price = $product->get_variation_sale_price( 'max' );

	$result_price = wc_price( $min_price );
	if ( $min_price !== $max_price || $min_sale_price !== $max_sale_price ){
		if ( $min_sale_price < $min_price ){
			$result_price = sprintf( __( 'From: <del>%1$s</del><ins>%2$s</ins>', 'woocommerce' ), $result_price, wc_price( $min_sale_price ) );
		} else {
			$result_price = sprintf( __( 'From: %1$s', 'woocommerce' ), $result_price );
		}
	}

    return $result_price;
}

add_filter( 'woocommerce_variable_price_html', 'dcms_variation_price_format', 10, 2 );


//Precios desde sin descuentos
function dcms_variation_price_format( $price, $product ) {

	$min_price = $product->get_variation_price( 'min' );
	$max_price = $product->get_variation_price( 'max' );

	$result_price = wc_price( $min_price );

    if ( $min_price !== $max_price ) {
		$result_price = sprintf( __( 'From: %1$s', 'woocommerce' ), $result_price );
	}

    return $result_price;
}
add_filter( 'woocommerce_variable_price_html', 'dcms_variation_price_format', 10, 2 );




//Otro codigo precios desde
add_filter( 'woocommerce_variable_sale_price_html', 'wc_custom_variation_price_format', 10, 2 );
add_filter( 'woocommerce_variable_price_html', 'wc_custom_variation_price_format', 10, 2 );

function wc_custom_variation_price_format( $price, $product ) {

  // Main Price
  $prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
  $price = $prices[0] !== $prices[1] ? sprintf( __( 'Desde: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

  // Sale Price
  $prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
  sort( $prices );
  $saleprice = $prices[0] !== $prices[1] ? sprintf( __( 'Desde: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );

  if ( $price !== $saleprice ) {
    $price = '<del>' . $saleprice . $product->get_price_suffix() . '</del> <ins>' . $price . 
    $product->get_price_suffix() . '</ins>';
  }
  return $price;
}

Códigos para la página de producto

Dentro de todos los códigos woocommerce para el functions que estamos mostrando, en la página de producto podemos hacer más cosas de las que nos brinda Woocommerce o el tema que tengamos elegido. Así pues te voy a mostrar algunos de los códigos que implementan funcionalidades extra dentro de la página de producto:

Código para personalizar el botón de añadir al carrito»

//* Personaliza el botón "Añadir al carro" en la página de un producto con WooCommerce:
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woo_custom_cart_button_text' );
function woo_custom_cart_button_text() {

	global $woocommerce;

	foreach($woocommerce->cart->get_cart() as $cart_item_key => $values ) {
		$_product = $values['data'];
		if( get_the_ID() == $_product->id ) {
			return __('Ya en el carrito - ¿Quieres añadirlo otra vez?', 'woocommerce');
		}
	}
	
	return __('Add to cart', 'woocommerce');
}

Código para personalizar el botón de añadir al carrito» versión 2

Hay un código que quizá sea incluso más eficaz que el anterior, ya que nos sirve para cambiar cadenas de texto sin llegar a tocar las traducciones, aunque no funciona si hay variables tipo nº de pedido en Woocommerce donde se deberían de cambiar desde los archivos .po/.mo de las traducciones.

El código en cuestión es el siguiente:

//Cambia la cadena de texto
function sustitucion_textos_predefinidos($traduccion){
    $palabras = array(
        'Añadir al carro' => 'Comprar ahora',
        
    );
    $traduccion = str_ireplace(array_keys($palabras), $palabras, $traduccion);
    return $traduccion;
}
add_filter('gettext', 'sustitucion_textos_predefinidos');
add_filter('ngettext', 'sustitucion_textos_predefinidos');

Código para saltar el carro e ir directo al checkout de pago

Este es un clásico y es muy eficiente por que en temas de compras por impulso evita que el cliente pueda abandonar el carrito al no pasar por el e ir directo a la página de pago. Antes de poner este código debemos de ir a Woocommerce/Ajustes/Productos y ahí marcar la opción «Activar botones AJAX de añadir al carrito en los archivos».

add_filter ('add_to_cart_redirect', 'redirect_to_checkout');
function redirect_to_checkout() {
	global $woocommerce;
	$checkout_url = $woocommerce->cart->get_checkout_url();
	return $checkout_url;
}

Código para mostrar avisos para envío gratuito

Aquí hay dos códigos interesantes, por un lado el de mostrar avisos para envío gratuito a partir de x euros, y por otro el de aviso de que ya tienes el producto que vas a clicar en el carro.

/*Mostrar avisos para envío gratuito*/
add_action( 'woocommerce_before_checkout_form_cart_notices', 'dl_notificacion_envio_carrito_checkout', 10, 0 );
function dl_notificacion_envio_carrito_checkout() {
	if ( is_checkout() && WC()->cart ) {
		$total = WC()->cart->get_cart_contents_total(); // Después del dto
		$limit = 50.00; // Pon aquí cual es el precio del envío gratuito
		// Condicional si el carrito es inferior a la cantidad
		if ( $total < $limit ) {
			// Calcular diferencia
			$diff = $limit - $total;
			$diff_formatted = wc_price( $diff );
			// Mostrar aviso
			wc_add_notice( sprintf( "Añade %s para tener el envío gratuito!", $diff_formatted ), 'notice' );
		}
	}
}

Código para avisar de que el producto ya está en el carrito

//Aviso de que el producto ya está en el carrito
function mys_ya_carrito_ficha () {
	global $woocommerce;
	foreach ($woocommerce -> cart -> get_cart () as $cart_item_key => $values ) {
		$_product = $values ['data'];
		if (get_the_ID () == $_product -> id)
			return 'Ya está en el carrito';
	}
	return __('Add to cart', 'woocommerce');
}
add_filter ('woocommerce_product_single_add_to_cart_text', 'mys_ya_carrito_ficha');

function mys_ya_carrito_archivo () {
	global $woocommerce;
	foreach($woocommerce -> cart -> get_cart () as $cart_item_key => $values ) {
		$_product = $values ['data'];
		if (get_the_ID () == $_product -> id )
			return 'El producto ya está en el carrito';
	}
	return __('Add to cart', 'woocommerce');
}
add_filter ('woocommerce_product_add_to_cart_text', 'mys_ya_carrito_archivo');

Códigos para la página de checkout de Woocommerce

La página de checkout o página de pago es una de las más importantes de nuestra tienda. Todo lo que pasa en ella va a ayudar (o no) a que vendamos nuestros productos. Aquí tienes más códigos woocommerce para el functions enfocados al checkout y de fácil implementación.

Código para eliminar campos del checkout (sólo si no son necesarios u obligatorios)

  add_filter('woocommerce_billing_fields','mys_custom_billing_fields');
  // remove some fields from billing form
  // ref - https://docs.woothemes.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
  function mys_custom_billing_fields( $fields = array() ) {
  
      unset($fields['billing_company']);
      unset($fields['billing_address_1']);
      unset($fields['billing_address_2']);
      unset($fields['billing_state']);
      unset($fields['billing_city']);
      unset($fields['billing_phone']);
      unset($fields['billing_postcode']);
      unset($fields['billing_country']);
  
      return $fields;
  }

Código para añadir campo CIF a a la factura

Con este código le podemos añadir un campo CIF a la factura que se adjunte si utilizamos plugins como pdf invoices & packing slips. Podremos añadir este campo como «billing_vat_number» o el nombre que le demos desde el plugin Woocommerce Chechout fields manager.

  add_filter( 'wpo_wcpdf_billing_address', 'incluir_nif_en_factura', 99, 2 );
function incluir_nif_en_factura( $address, $document = null ) {
    if (!empty($document->order) && $nif = $document->get_custom_field('billing_vat_number') ) {
        $address = $address . "<p>NIF/DNI/CIF: {$nif}</p>";
    }
    return $address;
}

Código para desactivar envíos a Canarias, Ceuta y Melilla

Diré que no es lo suyo, ya que si vendes en todo el territorio español, deberías de dar la oportunidad de poder vender en Canarias, Ceuta y Melilla, pero a menudo por tema aduanas y dependiendo de nuestro tipo de productos, optamos por no vender directamente allí.

Sólo hay que añadir el siguiente código para desactivar envíos (puedes añadir la provincia que quieras):

function mys_limita_envios ($provincias) {
	unset ($provincias ['ES'] ['TF']);
	unset ($provincias ['ES'] ['GC']);
	unset ($provincias ['ES'] ['CE']);
	unset ($provincias ['ES'] ['ML']);
	return $provincias;
	}
 
 add_filter ('woocommerce_states', 'mys_limita_envios');

Código para ocultar envíos si el envío gratuito existe

//Ocultar resto de envíos si envío gratuito existe
add_filter( 'woocommerce_package_rates', 'mys_unset_shipping_when_free_is_available_all_zones', 10, 2 );
   
function mys_unset_shipping_when_free_is_available_all_zones( $rates, $package ) {
      
  $all_free_rates = array();
     
  foreach ( $rates as $rate_id => $rate ) {
    if ( 'free_shipping' === $rate->method_id ) {
       $all_free_rates[ $rate_id ] = $rate;
       break;
    }
  }
     
  if ( empty( $all_free_rates )) {
    return $rates;
  } else {
    return $all_free_rates;
  } 
 
}

Código para forzar automáticamente el estado de los pedidos a «Completado»

A veces necesitamos que todos nuestros pedidos pasen a «completados», bien por que no tengamos como método de pago transferencia bancaria o contrareembolso, o bien porque hay algún problema relacionado con la pasarela de pago, el certificado ssl o similar que hace que una vez el cliente «ha salido» de la web hacia la pasarela de pago, en su regreso no «vuelva» con los datos necesarios como para hacer que Woocommerce cierre el pedido.

Para ello debemos de localizar primero los «codigos» de cada tipo de pago, aunque aquí tienes los que como digo más se utilizan que serían «paypal», «bizum», «cod» y «redsys».

add_action( 'woocommerce_order_status_processing', 'actualiza_estado_pedidos_a_completado' );
add_action( 'woocommerce_order_status_on-hold', 'actualiza_estado_pedidos_a_completado' );
function actualiza_estado_pedidos_a_completado( $order_id ) {
    global $woocommerce;
    
    //ID's de las pasarelas de pago a las que afecta
    $paymentMethods = array( 'paypal', 'bizum', 'cod', 'redsys' );
    
    if ( !$order_id ) return;
    $order = new WC_Order( $order_id );

    if ( !in_array( $order->payment_method, $paymentMethods ) ) return;
    $order->update_status( 'completed' );
}

Clase para CSS que añade una imagen a nuestros métodos de pago en el checkout

Aquí hay un extra, no es una función como tal, ya que está relacionada con el css. Con esta clase podrás añadir la imagen que quieras al método de pago que quieras. Tienes que localizar la clase y subir una imagen a la biblioteca de medios antes.

.payment_method_bacs label:after{
    content:»»;
    background-image: url(https://www.tudominio.es/wp-content/uploads/2022/03/imagen.png);
    background-size: 40px;
    background-repeat: no-repeat;
    margin-left: 12px;
    vertical-align: middle;
    width: 100px;
    height: 40px;
    display:inline-block;
}

Evidentemente que hay muchísismos más códigos para complementar nuestro Woocommerce, pero éstos quizá sean los que la gente más necesita, y seguramente se me olvide alguno conocidísimo y que utilizamos en casi todas las tiendas online, pero bueno, espero que los que he puesto aquí os sirvan de ayuda.

¿Necesitas ayuda?
Ir al contenido