T.Doe T.Doe - 4 months ago 15
PHP Question

WooCommerce product categories custom fields - Setting time purchasing restrictions

I have a Wordpress/WooCommerce site that displays categorized products. I'm trying to create a custom field in Admin individual categories pages (backend), where I can set a start and end time related to categorized products purchase availability.

How this should work:

The customers could only purchase products which category is "open" (between the start and end time set to this category) but all products will still visible even if they are not purchasable.

I was wondering if someone has an idea about the best way to begin and achieve that.

For the moment here is the related code that I have:

function custom_product_taxonomy_add_new_meta_field() { //add term page
//this will add the custom meta field to the add new term page
?>
<div class="form-field">
<label for="term_meta[custom_term_meta]"><?php _e( 'Post Code(s)' ); ?></label>
<input type="text" name="term_meta[custom_term_meta]" id="term_meta[custom_term_meta]" value="">
<p class="description"><?php _e( 'Enter the delivery post codes available for this store.','my-text-domain' ); ?></p>
</div>
<?php
}
add_action( 'product_cat_add_form_fields', 'custom_product_taxonomy_add_new_meta_field', 10, 2 );
//edit term page
function custom_product_taxonomy_edit_meta_field($term) {
//put the term ID into a variable
$t_id = $term->term_id;
//retrieve the existing value(s) for this meta field. This returns an array
$term_meta = get_option( "taxonomy_$t_id" ); ?>
<tr class="form-field">
<th scope="row" valign="top"><label for="term_meta[custom_term_meta]"><?php _e( 'Post Code(s)' ); ?></label></th>
<td>
<input type="text" name="term_meta[custom_term_meta]" id="term_meta[custom_term_meta]" value="<?php echo esc_attr( $term_meta['custom_term_meta'] ) ? esc_attr( $term_meta['custom_term_meta'] ) : ''; ?>">
<p class="description"><?php _e( 'Enter the delivery post codes available for this store.' ); ?></p>
</td>
</tr>
<?php
}
add_action( 'product_cat_edit_form_fields', 'custom_product_taxonomy_edit_meta_field', 10, 2 );
//save extra taxonomy fields callback function.
function save_taxonomy_custom_meta( $term_id ) {
if ( isset( $_POST['term_meta'] ) ) {
$t_id = $term_id;
$term_meta = get_option( "taxonomy_$t_id" );
$cat_keys = array_keys( $_POST['term_meta'] );
foreach ( $cat_keys as $key ) {
if ( isset ( $_POST['term_meta'][$key] ) ) {
$term_meta[$key] = $_POST['term_meta'][$key];
}
}
update_option( "taxonomy_$t_id", $term_meta ); //save the option array.
}
}
add_action( 'edited_product_cat', 'save_taxonomy_custom_meta', 10, 2 );
add_action( 'create_product_cat', 'save_taxonomy_custom_meta', 10, 2 );


This code adds a custom field in Admin categories pages, but like I have said before, I am looking for a custom field where I can set a starting and ending time.

Please any suggestions are welcome, as I've been on this for weeks and just looking for solutions.

Thanks in advance.

Answer

Concerning the time availability of product categories, I have chose to add 2 custom selectors, one for the start time and one for the end time:

screen-prod_cat-time-selectors

In the code snippet bellow, we create that 2 editable custom fields (The code is very compact since I use a for loop to generate the hours selector options, instead of displaying 24 hours options):

add_action( 'product_cat_edit_form_fields', 'availiability_product_taxonomy_edit_meta_field', 10, 2 );
add_action( 'product_cat_add_form_fields', 'availiability_product_taxonomy_edit_meta_field', 10, 2 );
function availiability_product_taxonomy_edit_meta_field($term) {
    //put the term ID into a variable
    $term_id = $term->term_id;
    //retrieve the start and ends values
    $start_time = get_term_meta( $term_id, 'start_time', true );
    $ends_time = get_term_meta( $term_id, 'ends_time', true );
    ?>

    <tr class="form-field">
        <th scope="row" valign="top">
            <label for="term_meta[custom_term_meta]"><?php _e( 'Time availiability' ,'my-theme-slug' ); ?></label>
        </th>
        <td>
            <span style="padding-right:12px">
            <label for="start_time"><?php _e( "Start" ,"my-theme-slug" ); ?></label>
            <select name="start_time" id="start_time" class="postform">

        <?php // Genereting the 24 options tags
            for ($i = 0; $i < 24; $i++) {
                $j = $i < 10 ? '0'.$i : ''.$i ; // values with on 2 digits
                $selected = $start_time == $j ? "selected" : "";
        ?>
                <option <?php echo $selected; ?> value="<?php echo $j; ?>"><?php echo $j; ?></option>
        <?php } ?>

            </select>
            </span>
            <span style="padding-right:12px">
            <label for="ends_time"><?php _e( "Ends" ,"my-theme-slug" ); ?></label>
            <select name="ends_time" id="ends_time" class="postform">

        <?php // Genereting the 24 options tags
            for ($i = 0; $i < 24; $i++) {
                $j = $i < 10 ? '0'.$i : ''.$i ; // values with on 2 digits
                $selected = $ends_time == $j ? "selected" : "";
        ?>
                <option <?php echo $selected; ?> value="<?php echo $j; ?>"><?php echo $j; ?></option>
        <?php } ?>

            </select>
            </span>
            <span>
                <em>(hours)</em>
            </span>
        </td>
    </tr>

    <?php
}

Then in the code snippet below we save de data when submitted.

add_action( 'create_product_cat', 'availiability_taxonomy_custom_meta', 10, 2 );
add_action( 'edited_product_cat', 'availiability_taxonomy_custom_meta', 10, 2 );
function availiability_taxonomy_custom_meta( $term_id ) {
  if ( isset( $_POST['start_time'] ) ) {
      add_term_meta ($term_id, 'start_time', $_POST['start_time'], true);
  }
  if ( isset( $_POST['ends_time'] ) ) {
      add_term_meta ($term_id, 'ends_time', $_POST['ends_time'], true);
  }
}

And in your database if you look in wp_termmeta table you will see for your category ID (here it is ID 11 when testing) the 2 custom fields with the corresponding values:

Custom fields for product categories (screenshot)

This code is using more recent functions included since WordPress 4.4+

add_term_meta() and get_term_meta() functions

All this code is tested and fully functional. It goes in function.php file located in your active child theme or theme.

A very good reference (using new core functions): Add custom field to Category