NB: Make sure you do a back up of your theme, files and database before attempting the tutorials

Hard

---- Last modified : May 11 2022

With this tutorial, we will create a new WordPress metabox for our downloadable WooCommerce products.

Our data would allow us to diplay the date where the number of days where the updates were done.

So let’s say you’re selling downloadable products. You want your customers to see the last date when the product was updated.

Creating a class for a WordPress metabox

As you’ll notice, our metabox has a date field by default.

// Meta Box Class: Woocommerce Product Update
class woocommerceproductupMetabox {

	private $screen = array(
		'product',
	);

	private $meta_fields = array(
		array(
			'label' => 'Recent updates for this product ?',
			'id' => 'woocommerce-update-product',
			'default' => 'Aujourdhui',
			'type' => 'date',
		),
	);

	public function __construct() {
		add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
		add_action( 'save_post', array( $this, 'save_fields' ) );
	}

	public function add_meta_boxes() {
		foreach ( $this->screen as $single_screen ) {
			add_meta_box(
				'woocommerceproductup',
				__( 'Woocommerce Product Update', 'textdomain' ),
				array( $this, 'meta_box_callback' ),
				$single_screen,
				'normal',
				'high'
			);
		}
	}

	public function meta_box_callback( $post ) {
		wp_nonce_field( 'woocommerceproductup_data', 'woocommerceproductup_nonce' );
		$this->field_generator( $post );
	}

	public function field_generator( $post ) {
		$output = '';
		foreach ( $this->meta_fields as $meta_field ) {
			$label = '<label for="' . $meta_field['id'] . '">' . $meta_field['label'] . '</label>';
			$meta_value = get_post_meta( $post->ID, $meta_field['id'], true );
			if ( empty( $meta_value ) ) {
				if ( isset( $meta_field['default'] ) ) {
					$meta_value = $meta_field['default'];
				}
			}
			switch ( $meta_field['type'] ) {
				default:
					$input = sprintf(
						'<input %s id="%s" name="%s" type="%s" value="%s">',
						$meta_field['type'] !== 'color' ? 'style="width: 100%"' : '',
						$meta_field['id'],
						$meta_field['id'],
						$meta_field['type'],
						$meta_value
					);
			}
			$output .= $this->format_rows( $label, $input );
		}
		echo '<table class="form-table"><tbody>' . $output . '</tbody></table>';
	}

	public function format_rows( $label, $input ) {
		return '<tr><th>'.$label.'</th><td>'.$input.'</td></tr>';
	}

	public function save_fields( $post_id ) {
		if ( ! isset( $_POST['woocommerceproductup_nonce'] ) )
			return $post_id;
		$nonce = $_POST['woocommerceproductup_nonce'];
		if ( !wp_verify_nonce( $nonce, 'woocommerceproductup_data' ) )
			return $post_id;
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
			return $post_id;
		foreach ( $this->meta_fields as $meta_field ) {
			if ( isset( $_POST[ $meta_field['id'] ] ) ) {
				switch ( $meta_field['type'] ) {
					case 'email':
						$_POST[ $meta_field['id'] ] = sanitize_email( $_POST[ $meta_field['id'] ] );
						break;
					case 'text':
						$_POST[ $meta_field['id'] ] = sanitize_text_field( $_POST[ $meta_field['id'] ] );
						break;
				}
				update_post_meta( $post_id, $meta_field['id'], $_POST[ $meta_field['id'] ] );
			} else if ( $meta_field['type'] === 'checkbox' ) {
				update_post_meta( $post_id, $meta_field['id'], '0' );
			}
		}
	}
}

if (class_exists('woocommerceproductupMetabox')) {
	new woocommerceproductupMetabox;
};

Visual of our WooCommerce product metabox

Metabox pour vos produits WooCommerce

Adding the update date in the loop of our product

Donc nous allons utiliser le hook woocommerce_before_shop_loop_item_title

This hook will allow us to position our get_post_meta of the de woocommerce-update-product name before the product’s title inside the loop, i.e. in product pages’ results.

We can also customize the date. With this hook, we will display the date however we see fit.

add_action( 'woocommerce_before_shop_loop_item_title', 'themespress_field_display_below_title', 2 );
function themespress_field_display_below_title(){
    global $product;
    // Get the custom field value
    $custom_field = get_post_meta( $product->get_id(), 'woocommerce-update-product', true );
    // Display
    if( ! empty($custom_field) ){
        echo '<p class="last-updates" style="position:absolute;top:30px;background:#f95b26;color:white;padding:2px 5px">' . 'MAJ : ' . (new DateTime($custom_field))->format('d M Y') . '</p>';
    }
}

Or we can edit the hook so we can display the n number of days since the last update of the WooCommerce product.

add_action( 'woocommerce_before_shop_loop_item_title', 'themespressdeux_field_display_below_title', 2 );
function themespressdeux_field_display_below_title(){
    global $product;
    // Get the custom field value
    $custom_field = get_post_meta( $product->get_id(), 'woocommerce-update-product', true );
    // Display
	$now = time(); // Current time 
	$your_date = strtotime($custom_field); // The first date
	$datediff = abs($now - $your_date); // Gives absolute Value
    if( ! empty($custom_field) ){ 
		echo '<p class="last-updates" style="position:absolute;top:30px;background:#f95b26;color:white;padding:2px 5px">' . 'MAJ : ' . floor($datediff/(60*60*24)) . '&nbsp;jour(s)' . '</p>';
    }
}

We strongly advise against copying it twice. Choose the first or second example.

Display the get_post_meta in the WooCommerce product

All that’s left to do now is use the woocommerce_before_single_product_summary hook in order to display the information about the product.

add_action( 'woocommerce_before_single_product_summary' , 'themespress_updates_date_before_product_title', 5 );
function themespress_updates_date_before_product_title() {
    global $product;
    // Get the custom field value
    $custom_field = get_post_meta( $product->get_id(), 'woocommerce-update-product', true );
    // Display
	$now = time(); // Current time 
	$your_date = strtotime($custom_field); // The first date
	$datediff = abs($now - $your_date); // Gives absolute Value
    if( ! empty($custom_field) ){ 
		echo '<p class="last-updates" style="position:absolute;top:-40px;right:0;background:#f95b26;color:white;padding:2px 5px">' . 'MAJ : ' . floor($datediff/(60*60*24)) . '&nbsp;jour(s)' . '</p>';
    }
}

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>