Enabled product bundles

This commit is contained in:
Nedim Uka
2018-06-29 14:40:28 +02:00
parent e0514f7f57
commit b5475ff2f1
12004 changed files with 1694047 additions and 1610 deletions

View File

@@ -0,0 +1,863 @@
<?php
/**
* Booster for WooCommerce - Product Input Fields - Core
*
* @version 3.7.0
* @author Algoritmika Ltd.
*/
if ( ! defined( 'ABSPATH' ) ) exit;
if ( ! class_exists( 'WCJ_Product_Input_Fields_Core' ) ) :
class WCJ_Product_Input_Fields_Core {
/** @var string scope. */
public $scope = '';
/**
* Constructor.
*
* @version 3.4.0
* @todo save all info (e.g. label etc.) in order meta
* @todo add `do_shortcode()` to all applicable options (e.g. "Message on required")
*/
function __construct( $scope ) {
$this->scope = $scope;
if ( 'yes' === get_option( 'wcj_product_input_fields_' . $this->scope . '_enabled', 'no' ) ) {
// Show fields at frontend
add_action( get_option( 'wcj_product_input_fields_position', 'woocommerce_before_add_to_cart_button' ),
array( $this, 'add_product_input_fields_to_frontend' ), get_option( 'wcj_product_input_fields_position_priority', 100 ) );
// Process from $_POST to cart item data
add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_product_input_fields_on_add_to_cart' ), 100, 2 );
add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_product_input_fields_to_cart_item_data' ), 100, 3 );
// from session
add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_product_input_fields_from_session' ), 100, 3 );
// Show details at cart, order details, emails
if ( 'data' === get_option( 'wcj_product_input_fields_display_options', 'name' ) ) {
add_filter( 'woocommerce_get_item_data', array( $this, 'add_product_input_fields_to_cart_item_display_data' ), PHP_INT_MAX, 2 );
} else {
add_filter( 'woocommerce_cart_item_name', array( $this, 'add_product_input_fields_to_cart_item_name' ), 100, 3 );
}
add_filter( 'woocommerce_order_item_name', array( $this, 'add_product_input_fields_to_order_item_name' ), 100, 2 );
// Add item meta from cart to order
if ( WCJ_IS_WC_VERSION_BELOW_3 ) {
add_action( 'woocommerce_add_order_item_meta', array( $this, 'add_product_input_fields_to_order_item_meta' ), 100, 3 );
} else {
add_action( 'woocommerce_new_order_item', array( $this, 'add_product_input_fields_to_order_item_meta_wc3' ), 100, 3 );
}
// Make nicer name for product input fields in order at backend (shop manager)
add_action( 'woocommerce_after_order_itemmeta', array( $this, 'output_custom_input_fields_in_admin_order' ), 100, 3 );
if ( 'yes' === get_option( 'wcj_product_input_fields_make_nicer_name_enabled', 'yes' ) ) {
add_filter( 'woocommerce_hidden_order_itemmeta', array( $this, 'hide_custom_input_fields_default_output_in_admin_order' ), 100 );
}
// Add to emails
add_filter( 'woocommerce_email_attachments', array( $this, 'add_files_to_email_attachments' ), PHP_INT_MAX, 3 );
if ( 'local' === $this->scope ) {
// Product Edit
add_action( 'add_meta_boxes', array( $this, 'add_local_product_input_fields_meta_box_to_product_edit' ) );
add_action( 'save_post_product', array( $this, 'save_local_product_input_fields_on_product_edit' ), 999, 2 );
}
}
}
/**
* Save product input fields on Product Edit.
*
* @version 3.5.0
*/
function save_local_product_input_fields_on_product_edit( $post_id, $post ) {
// Check that we are saving with input fields displayed.
if ( ! isset( $_POST['woojetpack_product_input_fields_save_post'] ) ) {
return;
}
// Save values
$default_total_input_fields = apply_filters( 'booster_option', 1, get_option( 'wcj_product_input_fields_local_total_number_default', 1 ) );
$total_input_fields_before_saving = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_product_input_fields_local_total_number', $post_id, 1 ) );
$total_input_fields_before_saving = ( '' != $total_input_fields_before_saving ) ? $total_input_fields_before_saving : $default_total_input_fields;
$options = $this->get_options();
$values = array();
$values['local_total_number'] = isset( $_POST['wcj_product_input_fields_local_total_number'] ) ?
$_POST['wcj_product_input_fields_local_total_number'] : $default_total_input_fields;
for ( $i = 1; $i <= $total_input_fields_before_saving; $i++ ) {
foreach ( $options as $option ) {
$option_name = str_replace( 'wcj_product_input_fields_', '', $option['id'] . $i );
if ( isset( $_POST[ $option['id'] . $i ] ) ) {
$values[ $option_name ] = $_POST[ $option['id'] . $i ];
} elseif ( 'checkbox' === $option['type'] ) {
$values[ $option_name ] = 'off';
}
}
}
update_post_meta( $post_id, '_wcj_product_input_fields', $values );
}
/**
* add_local_product_input_fields_meta_box_to_product_edit.
*
* @version 2.4.8
*/
function add_local_product_input_fields_meta_box_to_product_edit() {
add_meta_box(
'wc-jetpack-product-input-fields',
__( 'Booster: Product Input Fields', 'woocommerce-jetpack' ),
array( $this, 'create_local_product_input_fields_meta_box' ),
'product',
'normal',
'high'
);
}
/**
* create_local_product_input_fields_meta_box.
*
* @version 3.5.0
* @todo output options via standard "meta-box" mechanism (and make "serialized" meta box type)
*/
function create_local_product_input_fields_meta_box() {
$meta_box_id = 'product_input_fields';
$meta_box_desc = __( 'Product Input Fields', 'woocommerce-jetpack' );
$options = $this->get_options();
// Get total number
$current_post_id = get_the_ID();
$this->maybe_update_local_input_fields( $current_post_id );
$option_name = 'wcj_' . $meta_box_id . '_local_total_number';
// If none total number set - check for the default
if ( ! ( $total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_product_input_fields_local_total_number', $current_post_id, 1 ) ) ) ) {
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_' . $meta_box_id . '_local_total_number_default', 1 ) );
}
// Start html
$html = '';
// Total number
$is_disabled = apply_filters( 'booster_message', '', 'readonly_string' );
$is_disabled_message = apply_filters( 'booster_message', '', 'desc' );
$html .= '<table>';
$html .= '<tr>';
$html .= '<th>';
$html .= __( 'Total number of ', 'woocommerce-jetpack' ) . $meta_box_desc;
$html .= '</th>';
$html .= '<td>';
$html .= '<input type="number" id="' . $option_name . '" name="' . $option_name . '" value="' . $total_number . '" ' . $is_disabled . '>';
$html .= '</td>';
$html .= '<td>';
$html .= __( 'Click "Update" product after you change this number.', 'woocommerce-jetpack' ) . '<br>' . $is_disabled_message;
$html .= '</td>';
$html .= '</td>';
$html .= '</tr>';
$html .= '</table>';
// The options
for ( $i = 1; $i <= $total_number; $i++ ) {
$data = array();
$html .= '<hr>';
$html .= '<h3>' . __( 'Product Input Field', 'woocommerce-jetpack' ) . ' #' . $i . '</h3>';
foreach ( $options as $option ) {
$option_id = $option['id'] . $i;
$option_value = $this->get_value( $option_id, $current_post_id, $option['default'] );
if ( 'checkbox' === $option['type'] )
$is_checked = checked( $option_value, 'on', false );
$select_options_html = '';
if ( 'select' === $option['type'] ) {
foreach( $option['options'] as $select_option_id => $select_option_label ) {
$select_options_html .= '<option value="' . $select_option_id . '"' . selected( $option_value, $select_option_id, false ) . '>' .
$select_option_label . '</option>';
}
}
switch ( $option['type'] ) {
case 'number':
case 'text':
$the_field = '<input class="widefat" type="' . $option['type'] . '" id="' . $option_id . '" name="' . $option_id . '" value="' . $option_value . '">';
break;
case 'textarea':
$the_field = '<textarea style="' . ( isset( $option['css'] ) ? $option['css'] : '' ) .
'" class="widefat" style="" id="' . $option_id . '" name="' . $option_id . '">' . $option_value . '</textarea>';
break;
case 'checkbox':
$the_field = '<input class="checkbox" type="checkbox" name="' . $option_id . '" id="' . $option_id . '" ' . $is_checked . ' />' . ' ' . $option['title'];
break;
case 'select':
$the_field = '<select class="widefat" id="' . $option_id . '" name="' . $option_id . '">' . $select_options_html . '</select>';
break;
}
$maybe_tooltip = ( isset( $option['short_title'] ) && $option['short_title'] != $option['title'] ? wc_help_tip( $option['title'], true ) : '' );
$data[] = array(
( isset( $option['short_title'] ) ? $option['short_title'] : $option['title'] ) . $maybe_tooltip,
$the_field,
);
}
$html .= wcj_get_table_html( $data, array( 'table_heading_type' => 'vertical', 'table_class' => 'widefat striped', 'columns_styles' => array( 'width:33%;' ) ) );
}
$html .= '<input type="hidden" name="woojetpack_' . $meta_box_id . '_save_post" value="woojetpack_' . $meta_box_id . '_save_post">';
// Output
echo $html;
}
/**
* get_options.
*
* @version 3.1.0
*/
function get_options() {
return require( 'wcj-product-input-fields-options.php' );
}
/**
* is_enabled_for_product_global.
*
* @version 3.1.0
* @since 3.1.0
*/
function is_enabled_for_product_global( $field_nr, $product_id ) {
return wcj_is_enabled_for_product( $product_id, array(
'include_products' => get_option( 'wcj_product_input_fields_in_products_' . 'global' . '_' . $field_nr, '' ),
'exclude_products' => get_option( 'wcj_product_input_fields_ex_products_' . 'global' . '_' . $field_nr, '' ),
'include_categories' => get_option( 'wcj_product_input_fields_in_cats_' . 'global' . '_' . $field_nr, '' ),
'exclude_categories' => get_option( 'wcj_product_input_fields_ex_cats_' . 'global' . '_' . $field_nr, '' ),
'include_tags' => get_option( 'wcj_product_input_fields_in_tags_' . 'global' . '_' . $field_nr, '' ),
'exclude_tags' => get_option( 'wcj_product_input_fields_ex_tags_' . 'global' . '_' . $field_nr, '' ),
) );
}
/**
* is_enabled.
*
* @version 3.1.0
* @since 3.1.0
*/
function is_enabled( $field_nr, $product_id ) {
$is_enabled = $this->get_value( 'wcj_product_input_fields_enabled_' . $this->scope . '_' . $field_nr, $product_id, 'no' );
return ( ( 'on' === $is_enabled || 'yes' === $is_enabled ) && ( 'local' === $this->scope || $this->is_enabled_for_product_global( $field_nr, $product_id ) ) );
}
/**
* add_files_to_email_attachments.
*
* @version 2.8.0
* @since 2.5.0
*/
function add_files_to_email_attachments( $attachments, $status, $order ) {
if (
( 'new_order' === $status && 'yes' === get_option( 'wcj_product_input_fields_attach_to_admin_new_order', 'yes' ) ) ||
( 'customer_processing_order' === $status && 'yes' === get_option( 'wcj_product_input_fields_attach_to_customer_processing_order', 'yes' ) )
) {
foreach ( $order->get_items() as $item_key => $item ) {
$product_id = $item['product_id'];
$total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $product_id, 1 ) );
for ( $i = 1; $i <= $total_number; $i++ ) {
$meta_key = 'wcj_product_input_fields_' . $this->scope . '_' . $i;
if ( ! WCJ_IS_WC_VERSION_BELOW_3 ) {
$meta_key = '_' . $meta_key;
}
$meta_exists = ( WCJ_IS_WC_VERSION_BELOW_3 ? isset( $item[ $meta_key ] ) : $item->meta_exists( $meta_key ) );
if ( $meta_exists ) {
$_value = ( WCJ_IS_WC_VERSION_BELOW_3 ? $item[ $meta_key ] : $item->get_meta( $meta_key ) );
$_value = maybe_unserialize( $_value );
if ( isset( $_value['wcj_type'] ) && 'file' === $_value['wcj_type'] && isset( $_value['tmp_name'] ) ) {
$file_path = $_value['tmp_name'];
$attachments[] = $file_path;
}
}
}
}
}
return $attachments;
}
/**
* hide_custom_input_fields_default_output_in_admin_order.
*
* @todo get actual (max) number of fields in case of local scope
*/
function hide_custom_input_fields_default_output_in_admin_order( $hidden_metas ) {
$total_number = 0;
if ( 'global' === $this->scope ) {
$total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', 0, 1 ) );
} else {
$max_number_of_fields_for_local = 100;
$total_number = $max_number_of_fields_for_local;
}
for ( $i = 1; $i <= $total_number; $i++ ) {
$hidden_metas[] = '_' . 'wcj_product_input_fields_' . $this->scope . '_' . $i;
}
return $hidden_metas;
}
/**
* output_custom_input_fields_in_admin_order.
*
* @version 3.1.0
*/
function output_custom_input_fields_in_admin_order( $item_id, $item, $_product ) {
if ( null === $_product ) {
// Shipping
return;
}
echo '<table cellspacing="0" class="display_meta">';
$_product_id = wcj_get_product_id_or_variation_parent_id( $_product );
$total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $_product_id, 1 ) );
for ( $i = 1; $i <= $total_number; $i++ ) {
$the_nice_name = $this->get_value( 'wcj_product_input_fields_title_' . $this->scope . '_' . $i, $_product_id, '' );
if ( '' == $the_nice_name ) $the_nice_name = __( 'Product Input Field', 'woocommerce-jetpack' ) . ' (' . $this->scope . ') #' . $i;
$the_value = isset( $item[ 'wcj_product_input_fields_' . $this->scope . '_' . $i ] ) ? $item[ 'wcj_product_input_fields_' . $this->scope . '_' . $i ] : '';
$type = $this->get_value( 'wcj_product_input_fields_type_' . $this->scope . '_' . $i, $_product_id, '' );
if ( 'file' === $type ) {
$the_value = maybe_unserialize( $the_value );
if ( isset( $the_value['name'] ) ) {
$the_value = '<a href="' . add_query_arg( 'wcj_download_file', $item_id . '.' . pathinfo( $the_value['name'], PATHINFO_EXTENSION ) ) . '">' . $the_value['name'] . '</a>';
}
} else {
if ( 'no' === get_option( 'wcj_product_input_fields_make_nicer_name_enabled', 'yes' ) ) {
continue;
}
}
if ( '' != $the_value ) {
echo '<tr><th>' . $the_nice_name . ':</th><td>' . $the_value . '</td></tr>';
}
}
echo '</table>';
}
/**
* get_value.
*
* @version 3.5.0
* @todo `wcj_get_product_input_field_value()` is almost identical
*/
function get_value( $option_name, $product_id, $default ) {
if ( 'global' === $this->scope ) {
return get_option( $option_name, $default );
} else { // local
if ( '' != ( $options = get_post_meta( $product_id, '_' . 'wcj_product_input_fields', true ) ) ) {
$option_name = str_replace( 'wcj_product_input_fields_', '', $option_name );
return ( isset( $options[ $option_name ] ) ? $options[ $option_name ] : $default );
} else { // Booster version < 3.5.0
return get_post_meta( $product_id, '_' . $option_name, true );
}
}
}
/**
* validate_product_input_fields_on_add_to_cart.
*
* @version 3.1.0
*/
function validate_product_input_fields_on_add_to_cart( $passed, $product_id ) {
$total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $product_id, 1 ) );
for ( $i = 1; $i <= $total_number; $i++ ) {
if ( ! $this->is_enabled( $i, $product_id ) ) {
continue;
}
$type = $this->get_value( 'wcj_product_input_fields_type_' . $this->scope . '_' . $i, $product_id, '' );
$field_name = 'wcj_product_input_fields_' . $this->scope . '_' . $i;
if ( 'checkbox' === $type && ! isset( $_POST[ $field_name ] ) ) {
$_POST[ $field_name ] = 'off';
}
$is_required = $this->get_value( 'wcj_product_input_fields_required_' . $this->scope . '_' . $i, $product_id, 'no' );
if ( 'on' === $is_required || 'yes' === $is_required ) {
if ( 'file' === $type ) {
$field_value = ( isset( $_FILES[ $field_name ]['name'] ) ) ? $_FILES[ $field_name ]['name'] : '';
} else {
$field_value = ( isset( $_POST[ $field_name ] ) ) ? $_POST[ $field_name ] : '';
if ( 'checkbox' === $type && 'off' === $field_value ) {
$field_value = '';
}
}
if ( '' == $field_value ) {
$passed = false;
wc_add_notice( $this->get_value( 'wcj_product_input_fields_required_message_' . $this->scope . '_' . $i, $product_id, '' ), 'error' );
}
}
if ( 'file' === $type && isset( $_FILES[ $field_name ] ) && '' != $_FILES[ $field_name ]['name'] ) {
// Validate file type
if ( '' != ( $file_accept = $this->get_value( 'wcj_product_input_fields_type_file_accept_' . $this->scope . '_' . $i, $product_id, '' ) ) ) {
$file_accept = explode( ',', $file_accept );
if ( is_array( $file_accept ) && ! empty( $file_accept ) ) {
$file_type = '.' . pathinfo( $_FILES[ $field_name ]['name'], PATHINFO_EXTENSION );
if ( ! in_array( $file_type, $file_accept ) ) {
$passed = false;
wc_add_notice( __( 'Wrong file type!', 'woocommerce-jetpack' ), 'error' );
}
}
}
// Validate file max size
if ( ( $max_file_size = $this->get_value( 'wcj_product_input_fields_type_file_max_size_' . $this->scope . '_' . $i, $product_id, '' ) ) > 0 ) {
if ( $_FILES[ $field_name ]['size'] > $max_file_size ) {
$passed = false;
wc_add_notice( __( 'File is too big!', 'woocommerce-jetpack' ), 'error' );
}
}
}
}
return $passed;
}
/**
* maybe_update_local_input_fields.
*
* @version 3.5.0
* @since 3.5.0
* @todo (maybe) if `$total_number` is not set - use `$default_total_input_fields` instead
*/
function maybe_update_local_input_fields( $_product_id ) {
if ( 'local' != $this->scope ) {
return;
}
if ( '' != get_post_meta( $_product_id, '_' . 'wcj_product_input_fields', true ) ) {
return;
}
$values = array();
$options = $this->get_options();
$total_number = apply_filters( 'booster_option', 1, get_post_meta( $_product_id, '_' . 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', true ) );
$values[ $this->scope . '_total_number' ] = $total_number;
delete_post_meta( $_product_id, '_' . 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number' );
for ( $i = 1; $i <= $total_number; $i++ ) {
foreach ( $options as $option ) {
$option_id = $option['id'] . $i;
if ( metadata_exists( 'post', $_product_id, '_' . $option_id ) ) {
$option_value = get_post_meta( $_product_id, '_' . $option_id, true );
delete_post_meta( $_product_id, '_' . $option_id );
} else {
$option_value = $option['default'];
}
$values[ str_replace( 'wcj_product_input_fields_', '', $option_id ) ] = $option_value;
}
}
update_post_meta( $_product_id, '_wcj_product_input_fields', $values );
}
/**
* add_product_input_fields_to_frontend.
*
* @version 3.7.0
* @todo `$set_value` - add "default" option for all other types except checkbox
* @todo `$set_value` - 'file' type
* @todo add `required` attributes
*/
function add_product_input_fields_to_frontend() {
if ( isset( $this->are_product_input_fields_displayed ) ) {
return;
}
global $product;
if ( ! $product ) {
return;
}
$_product_id = wcj_get_product_id_or_variation_parent_id( $product );
$this->maybe_update_local_input_fields( $_product_id );
$fields = array();
$total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $_product_id, 1 ) );
for ( $i = 1; $i <= $total_number; $i++ ) {
$type = $this->get_value( 'wcj_product_input_fields_type_' . $this->scope . '_' . $i, $_product_id, 'text' );
$is_required = $this->get_value( 'wcj_product_input_fields_required_' . $this->scope . '_' . $i, $_product_id, 'no' );
$title = $this->get_value( 'wcj_product_input_fields_title_' . $this->scope . '_' . $i, $_product_id, '' );
$placeholder = $this->get_value( 'wcj_product_input_fields_placeholder_' . $this->scope . '_' . $i, $_product_id, '' );
$datepicker_format = $this->get_value( 'wcj_product_input_fields_type_datepicker_format_' . $this->scope . '_' . $i, $_product_id, '' );
if ( '' == $datepicker_format ) {
$datepicker_format = get_option( 'date_format' );
}
$datepicker_format = wcj_date_format_php_to_js( $datepicker_format );
$datepicker_mindate = $this->get_value( 'wcj_product_input_fields_type_datepicker_mindate_' . $this->scope . '_' . $i, $_product_id, -365 );
$datepicker_maxdate = $this->get_value( 'wcj_product_input_fields_type_datepicker_maxdate_' . $this->scope . '_' . $i, $_product_id, 365 );
$datepicker_firstday = $this->get_value( 'wcj_product_input_fields_type_datepicker_firstday_' . $this->scope . '_' . $i, $_product_id, 0 );
$datepicker_changeyear = $this->get_value( 'wcj_product_input_fields_type_datepicker_changeyear_' . $this->scope . '_' . $i, $_product_id, 'no' );
$datepicker_yearrange = $this->get_value( 'wcj_product_input_fields_type_datepicker_yearrange_' . $this->scope . '_' . $i, $_product_id, 'c-10:c+10' );
if ( 'on' === $datepicker_changeyear || 'yes' === $datepicker_changeyear ) {
$datepicker_year = 'changeyear="1" yearRange="' . $datepicker_yearrange . '" ';
} else {
$datepicker_year = '';
}
$timepicker_format = $this->get_value( 'wcj_product_input_fields_type_timepicker_format_' . $this->scope . '_' . $i, $_product_id, 'hh:mm p' );
$timepicker_interval = $this->get_value( 'wcj_product_input_fields_type_timepicker_interval_' . $this->scope . '_' . $i, $_product_id, 15 );
$timepicker_mintime = $this->get_value( 'wcj_product_input_fields_type_timepicker_mintime_' . $this->scope . '_' . $i, $_product_id, '' );
$timepicker_maxtime = $this->get_value( 'wcj_product_input_fields_type_timepicker_maxtime_' . $this->scope . '_' . $i, $_product_id, '' );
if ( '' != $timepicker_mintime ) {
$timepicker_mintime = ' mintime="' . $timepicker_mintime . '"';
}
if ( '' != $timepicker_maxtime ) {
$timepicker_maxtime = ' maxtime="' . $timepicker_maxtime . '"';
}
$file_accept = $this->get_value( 'wcj_product_input_fields_type_file_accept_' . $this->scope . '_' . $i, $_product_id, '' );
$custom_attributes = ( 'file' === $type ) ? ' accept="' . $file_accept . '"' : '';
$field_name = 'wcj_product_input_fields_' . $this->scope . '_' . $i;
if ( 'on' === $is_required || 'yes' === $is_required ) {
$title .= get_option( 'wcj_product_input_fields_frontend_view_required_html', '&nbsp;<abbr class="required" title="required">*</abbr>' );
}
if ( $this->is_enabled( $i, $_product_id ) ) {
$set_value = ( isset( $_POST[ $field_name ] ) ?
$_POST[ $field_name ] :
( 'checkbox' == $type ?
( 'yes' === $this->get_value( 'wcj_product_input_fields_type_checkbox_default_' . $this->scope . '_' . $i, $_product_id, 'no' ) ? 'on' : 'off' ) :
''
)
);
$html = '';
$class = $this->get_value( 'wcj_product_input_fields_class_' . $this->scope . '_' . $i, $_product_id, '' );
if ( '' != $class ) {
$class = ' ' . $class;
}
switch ( $type ) {
case 'number':
case 'text':
case 'file':
case 'password':
case 'email':
case 'tel':
$html = '<input value="' . $set_value . '" class="wcj_product_input_fields' . $class . '" id="' . $field_name . '" type="' . $type . '" name="' .
$field_name . '" placeholder="' . $placeholder . '"' . $custom_attributes . '>';
break;
case 'checkbox':
$checked = checked(
$set_value,
'on',
false
);
$html = '<input class="wcj_product_input_fields' . $class . '" id="' . $field_name . '" type="' . $type . '" name="' . $field_name . '"' .
$custom_attributes . $checked . '>';
break;
case 'datepicker':
$html = '<input value="' . $set_value . '" class="wcj_product_input_fields' . $class . '" id="' . $field_name . '" ' . $datepicker_year . 'firstday="' .
$datepicker_firstday . '" dateformat="' . $datepicker_format . '" mindate="' .
$datepicker_mindate . '" maxdate="' . $datepicker_maxdate . '" type="' .
$type . '" display="date" name="' . $field_name . '" placeholder="' . $placeholder . '"' . $custom_attributes . '>';
break;
case 'weekpicker':
$html = '<input value="' . $set_value . '" class="wcj_product_input_fields' . $class . '" id="' . $field_name . '" ' . $datepicker_year . 'firstday="' .
$datepicker_firstday . '" dateformat="' . $datepicker_format . '" mindate="' .
$datepicker_mindate . '" maxdate="' . $datepicker_maxdate . '" type="' .
$type . '" display="week" name="' . $field_name . '" placeholder="' . $placeholder . '"' . $custom_attributes . '>';
break;
case 'timepicker':
$html = '<input value="' . $set_value . '" class="wcj_product_input_fields' . $class . '" id="' . $field_name . '"' .
$timepicker_mintime . $timepicker_maxtime . ' interval="' . $timepicker_interval . '" timeformat="' .
$timepicker_format . '" type="' . $type . '" display="time" name="' . $field_name . '" placeholder="' .
$placeholder . '"' . $custom_attributes . '>';
break;
case 'textarea':
$html = '<textarea class="wcj_product_input_fields' . $class . '" id="' . $field_name . '" name="' . $field_name . '" placeholder="' . $placeholder . '">' .
$set_value . '</textarea>';
break;
case 'select':
$select_options_raw = $this->get_value( 'wcj_product_input_fields_type_select_options_' . $this->scope . '_' . $i, $_product_id, '' );
$select_options = wcj_get_select_options( $select_options_raw, false );
if ( '' != $placeholder ) {
$select_options = array_replace( array( '' => $placeholder ), $select_options );
}
$select_options_html = '';
if ( ! empty( $select_options ) ) {
reset( $select_options );
$value = ( '' != $set_value ? $set_value : key( $select_options ) );
foreach ( $select_options as $select_option_key => $select_option_title ) {
$select_options_html .= '<option value="' . $select_option_key . '" ' . selected( $value, $select_option_key, false ) . '>';
$select_options_html .= $select_option_title;
$select_options_html .= '</option>';
}
}
$html = '<select class="wcj_product_input_fields' . $class . '" id="' . $field_name . '" name="' . $field_name . '">' . $select_options_html . '</select>';
break;
case 'radio':
$select_options_raw = $this->get_value( 'wcj_product_input_fields_type_select_options_' . $this->scope . '_' . $i, $_product_id, '' );
$select_options = wcj_get_select_options( $select_options_raw, false );
$select_options_html = '';
if ( ! empty( $select_options ) ) {
reset( $select_options );
$value = ( '' != $set_value ? $set_value : key( $select_options ) );
$template = get_option( 'wcj_product_input_fields_field_template_radio',
'%radio_field_html%<label for="%radio_field_id%" class="radio">%radio_field_title%</label><br>' );
foreach ( $select_options as $option_key => $option_text ) {
$replaced_values = array(
'%radio_field_html%' => '<input type="radio" class="input-radio wcj_product_input_fields' . $class . '" value="' . esc_attr( $option_key ) .
'" name="' . $field_name . '" id="' . $field_name . '_' . esc_attr( $option_key ) . '"' . checked( $value, $option_key, false ) . ' />',
'%radio_field_id%' => $field_name . '_' . esc_attr( $option_key ),
'%radio_field_title%' => $option_text,
);
$select_options_html .= str_replace( array_keys( $replaced_values ), $replaced_values, $template );
}
$html = $select_options_html;
}
break;
case 'country':
$countries = WC()->countries->get_allowed_countries();
if ( sizeof( $countries ) > 1 ) {
$value = ( '' != $set_value ? $set_value : key( $countries ) );
$field = '<select name="' . $field_name . '" id="' . $field_name . '" class="country_to_state country_select wcj_product_input_fields' . $class . '">' .
'<option value="">'.__( 'Select a country&hellip;', 'woocommerce' ) .'</option>';
foreach ( $countries as $ckey => $cvalue ) {
$field .= '<option value="' . esc_attr( $ckey ) . '" '.selected( $value, $ckey, false ) .'>'.__( $cvalue, 'woocommerce' ) .'</option>';
}
$field .= '</select>';
$html = $field;
}
break;
}
$html = str_replace( array( '%field_title%', '%field_id%', '%field_html%' ), array( $title, $field_name, $html ),
get_option( 'wcj_product_input_fields_field_template', '<p><label for="%field_id%">%field_title%</label> %field_html%</p>' ) );
if ( 0 == ( $field_order = $this->get_value( 'wcj_product_input_fields_order_' . $this->scope . '_' . $i, $_product_id, 0 ) ) ) {
$field_order = $i;
}
$fields[ $field_order ] = apply_filters( 'wcj_product_input_field_frontend_html', $html, array(
'title' => do_shortcode( $title ),
'type' => $type,
'field_name' => $field_name,
'placeholder' => do_shortcode( $placeholder ),
'custom_attributes' => $custom_attributes,
'_product_id' => $_product_id,
'_field_nr' => $i,
'_scope' => $this->scope,
) );
}
}
ksort( $fields );
if ( ! empty ( $fields ) ) {
echo get_option( 'wcj_product_input_fields_start_template', '' ) . implode( $fields ) . get_option( 'wcj_product_input_fields_end_template', '' );
$this->are_product_input_fields_displayed = true;
}
}
/**
* add_product_input_fields_to_cart_item_data.
*
* from `$_POST` to `$cart_item_data`
*
* @version 3.1.0
*/
function add_product_input_fields_to_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
$total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $product_id, 1 ) );
for ( $i = 1; $i <= $total_number; $i++ ) {
if ( ! $this->is_enabled( $i, $product_id ) ) {
continue;
}
$type = $this->get_value( 'wcj_product_input_fields_type_' . $this->scope . '_' . $i, $product_id, '' );
$value_name = 'wcj_product_input_fields_' . $this->scope . '_' . $i;
if ( 'file' === $type ) {
if ( isset( $_FILES[ $value_name ] ) ) {
$cart_item_data[ $value_name ] = $_FILES[ $value_name ];
$tmp_dest_file = tempnam( sys_get_temp_dir(), 'wcj' );
move_uploaded_file( $cart_item_data[ $value_name ]['tmp_name'], $tmp_dest_file );
$cart_item_data[ $value_name ]['tmp_name'] = $tmp_dest_file;
}
} else {
if ( isset( $_POST[ $value_name ] ) ) {
$cart_item_data[ $value_name ] = $_POST[ $value_name ];
}
}
}
return $cart_item_data;
}
/**
* get_cart_item_product_input_fields_from_session.
*/
function get_cart_item_product_input_fields_from_session( $item, $values, $key ) {
$total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $item['product_id'], 1 ) );
for ( $i = 1; $i <= $total_number; $i++ ) {
if ( array_key_exists( 'wcj_product_input_fields_' . $this->scope . '_' . $i, $values ) )
$item[ 'wcj_product_input_fields_' . $this->scope . '_' . $i ] = $values[ 'wcj_product_input_fields_' . $this->scope . '_' . $i ];
}
return $item;
}
/**
* Adds product input values to order details (and emails).
*
* @version 3.1.0
*/
function add_product_input_fields_to_order_item_name( $name, $item, $is_cart = false ) {
$total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $item['product_id'], 1 ) );
if ( $total_number < 1 ) {
return $name;
}
if ( $is_cart ) {
$name .= get_option( 'wcj_product_input_fields_cart_start_template', '<dl style="font-size:smaller;">' );
$item_template = get_option( 'wcj_product_input_fields_cart_field_template', '<dt>%title%</dt><dd>%value%</dd>' );
} else {
$item_template = get_option( 'wcj_product_input_fields_frontend_view_order_table_format', '&nbsp;| %title% %value%' );
}
for ( $i = 1; $i <= $total_number; $i++ ) {
if ( ! $this->is_enabled( $i, $item['product_id'] ) ) {
continue;
}
$type = $this->get_value( 'wcj_product_input_fields_type_' . $this->scope . '_' . $i, $item['product_id'], '' );
$meta_key = 'wcj_product_input_fields_' . $this->scope . '_' . $i;
if ( ! WCJ_IS_WC_VERSION_BELOW_3 && ! $is_cart ) {
$meta_key = '_' . $meta_key;
}
$meta_exists = ( WCJ_IS_WC_VERSION_BELOW_3 || $is_cart ? array_key_exists( $meta_key, $item ) : $item->meta_exists( $meta_key ) );
if ( $meta_exists ) {
$value = ( WCJ_IS_WC_VERSION_BELOW_3 || $is_cart ? $item[ $meta_key ] : $item->get_meta( $meta_key ) );
} elseif ( 'checkbox' === $type ) {
$value = 'off';
$meta_exists = true;
}
if ( $meta_exists ) {
$title = $this->get_value( 'wcj_product_input_fields_title_' . $this->scope . '_' . $i, $item['product_id'], '' );
$yes_value = $this->get_value( 'wcj_product_input_fields_type_checkbox_yes_' . $this->scope . '_' . $i, $item['product_id'], '' );
$no_value = $this->get_value( 'wcj_product_input_fields_type_checkbox_no_' . $this->scope . '_' . $i, $item['product_id'], '' );
if ( 'checkbox' === $type ) {
$value = ( 'on' === $value ) ? $yes_value : $no_value;
}
if ( 'file' === $type ) {
$value = maybe_unserialize( $value );
$value = ( isset( $value['name'] ) ) ? $value['name'] : '';
}
if ( '' != $value && is_string( $value ) ) {
$name .= str_replace( array( '%title%', '%value%' ), array( $title, $value ), $item_template );
}
}
}
if ( $is_cart ) {
$name .= get_option( 'wcj_product_input_fields_cart_end_template', '</dl>' );
}
return $name;
}
/**
* Adds product input values to cart item details.
*
* @version 2.4.0
*/
function add_product_input_fields_to_cart_item_name( $name, $cart_item, $cart_item_key ) {
return $this->add_product_input_fields_to_order_item_name( $name, $cart_item, true );
}
/**
* add_product_input_fields_to_cart_item_display_data.
*
* @version 3.1.0
* @since 2.9.0
*/
function add_product_input_fields_to_cart_item_display_data( $item_data, $item ) {
$total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $item['product_id'], 1 ) );
if ( $total_number < 1 ) {
return $item_data;
}
for ( $i = 1; $i <= $total_number; $i++ ) {
if ( ! $this->is_enabled( $i, $item['product_id'] ) ) {
continue;
}
$type = $this->get_value( 'wcj_product_input_fields_type_' . $this->scope . '_' . $i, $item['product_id'], '' );
$meta_key = 'wcj_product_input_fields_' . $this->scope . '_' . $i;
$meta_exists = array_key_exists( $meta_key, $item );
if ( $meta_exists ) {
$value = $item[ $meta_key ];
} elseif ( 'checkbox' === $type ) {
$value = 'off';
$meta_exists = true;
}
if ( $meta_exists ) {
$title = $this->get_value( 'wcj_product_input_fields_title_' . $this->scope . '_' . $i, $item['product_id'], '' );
$yes_value = $this->get_value( 'wcj_product_input_fields_type_checkbox_yes_' . $this->scope . '_' . $i, $item['product_id'], '' );
$no_value = $this->get_value( 'wcj_product_input_fields_type_checkbox_no_' . $this->scope . '_' . $i, $item['product_id'], '' );
if ( 'checkbox' === $type ) {
$value = ( 'on' === $value ) ? $yes_value : $no_value;
}
if ( 'file' === $type ) {
$value = maybe_unserialize( $value );
$value = ( isset( $value['name'] ) ) ? $value['name'] : '';
}
if ( '' != $value ) {
$item_data[] = array(
'key' => $title,
'display' => $value,
);
}
}
}
return $item_data;
}
/**
* add_product_input_fields_to_order_item_meta_wc3.
*
* @version 3.4.0
* @since 3.4.0
* @todo this is only a temporary solution: must replace `$item->legacy_values` (check "Bookings" module - `woocommerce_checkout_create_order_line_item` hook)
*/
function add_product_input_fields_to_order_item_meta_wc3( $item_id, $item, $order_id ) {
if ( is_a( $item, 'WC_Order_Item_Product' ) ) {
$this->add_product_input_fields_to_order_item_meta( $item_id, $item->legacy_values, null );
}
}
/**
* add_product_input_fields_to_order_item_meta.
*
* @version 2.5.0
*/
function add_product_input_fields_to_order_item_meta( $item_id, $values, $cart_item_key ) {
$total_number = apply_filters( 'booster_option', 1, $this->get_value( 'wcj_' . 'product_input_fields' . '_' . $this->scope . '_total_number', $values['product_id'], 1 ) );
for ( $i = 1; $i <= $total_number; $i++ ) {
if ( array_key_exists( 'wcj_product_input_fields_' . $this->scope . '_' . $i , $values ) ) {
$type = $this->get_value( 'wcj_product_input_fields_type_' . $this->scope . '_' . $i, $values['product_id'], '' );
$input_field_value = $values[ 'wcj_product_input_fields_' . $this->scope . '_' . $i ];
if ( 'file' === $type ) {
$tmp_name = $input_field_value['tmp_name'];
$ext = pathinfo( $input_field_value['name'], PATHINFO_EXTENSION );
$name = $item_id . '.' . $ext;//$input_field_value['name'];
$upload_dir = wcj_get_wcj_uploads_dir( 'input_fields_uploads' );
if ( ! file_exists( $upload_dir ) ) {
mkdir( $upload_dir, 0755, true );
}
$upload_dir_and_name = $upload_dir . '/' . $name;
$file_data = file_get_contents( $tmp_name );
file_put_contents( $upload_dir_and_name, $file_data );
unlink( $tmp_name );
$input_field_value['tmp_name'] = addslashes( $upload_dir_and_name );
$input_field_value['wcj_type'] = 'file';
}
wc_add_order_item_meta( $item_id, '_wcj_product_input_fields_' . $this->scope . '_' . $i, $input_field_value );
}
}
}
}
endif;

View File

@@ -0,0 +1,218 @@
<?php
/**
* Booster for WooCommerce - Product Input Fields - Options
*
* @version 3.4.0
* @since 3.1.0
* @author Algoritmika Ltd.
*/
if ( ! defined( 'ABSPATH' ) ) exit;
return array(
array(
'id' => 'wcj_product_input_fields_enabled_' . $this->scope . '_',
'title' => __( 'Enabled', 'woocommerce-jetpack' ),
'type' => 'checkbox',
'default' => 'no',
),
array(
'id' => 'wcj_product_input_fields_order_' . $this->scope . '_',
'short_title' => __( 'Order', 'woocommerce-jetpack' ),
'title' => __( 'Set to zero for default order.', 'woocommerce-jetpack' ),
'type' => 'number',
'default' => 0,
),
array(
'id' => 'wcj_product_input_fields_type_' . $this->scope . '_',
'title' => __( 'Type', 'woocommerce-jetpack' ),
'type' => 'select',
'default' => 'text',
'options' => array(
'text' => __( 'Text', 'woocommerce-jetpack' ),
'textarea' => __( 'Textarea', 'woocommerce-jetpack' ),
'number' => __( 'Number', 'woocommerce-jetpack' ),
'checkbox' => __( 'Checkbox', 'woocommerce-jetpack' ),
'file' => __( 'File', 'woocommerce-jetpack' ),
'datepicker' => __( 'Datepicker', 'woocommerce-jetpack' ),
'weekpicker' => __( 'Weekpicker', 'woocommerce-jetpack' ),
'timepicker' => __( 'Timepicker', 'woocommerce-jetpack' ),
'select' => __( 'Select', 'woocommerce-jetpack' ),
'radio' => __( 'Radio', 'woocommerce-jetpack' ),
'password' => __( 'Password', 'woocommerce-jetpack' ),
'country' => __( 'Country', 'woocommerce-jetpack' ),
// 'state' => __( 'State', 'woocommerce-jetpack' ),
'email' => __( 'Email', 'woocommerce-jetpack' ),
'tel' => __( 'Phone', 'woocommerce-jetpack' ),
),
),
array(
'id' => 'wcj_product_input_fields_title_' . $this->scope . '_',
'title' => __( 'Title', 'woocommerce-jetpack' ),
'type' => 'textarea',
'default' => '',
),
array(
'id' => 'wcj_product_input_fields_placeholder_' . $this->scope . '_',
'title' => __( 'Placeholder', 'woocommerce-jetpack' ),
'type' => 'textarea',
'default' => '',
),
array(
'id' => 'wcj_product_input_fields_required_' . $this->scope . '_',
'title' => __( 'Required', 'woocommerce-jetpack' ),
'type' => 'checkbox',
'default' => 'no',
),
array(
'id' => 'wcj_product_input_fields_required_message_' . $this->scope . '_',
'title' => __( 'Message on required', 'woocommerce-jetpack' ),
'type' => 'textarea',
'default' => '',
),
array(
'id' => 'wcj_product_input_fields_class_' . $this->scope . '_',
'title' => __( 'HTML Class', 'woocommerce-jetpack' ),
'type' => 'text',
'default' => '',
),
/* array(
'id' => 'wcj_product_input_fields_type_checkbox_' . $this->scope . '_',
'title' => __( 'If checkbox is selected, set possible pairs here.', 'woocommerce-jetpack' ),
'type' => 'select',
'default' => 'yes_no',
'options' => array(
'yes_no' => __( 'Yes / No', 'woocommerce-jetpack' ),
'on_off' => __( 'On / Off', 'woocommerce-jetpack' ),
),
), */
array(
'id' => 'wcj_product_input_fields_type_checkbox_yes_' . $this->scope . '_',
'title' => __( 'If checkbox is selected, set value for ON here', 'woocommerce-jetpack' ),
'short_title' => __( 'Checkbox: ON', 'woocommerce-jetpack' ),
'type' => 'text',
'default' => __( 'Yes', 'woocommerce-jetpack' ),
),
array(
'id' => 'wcj_product_input_fields_type_checkbox_no_' . $this->scope . '_',
'title' => __( 'If checkbox is selected, set value for OFF here', 'woocommerce-jetpack' ),
'short_title' => __( 'Checkbox: OFF', 'woocommerce-jetpack' ),
'type' => 'text',
'default' => __( 'No', 'woocommerce-jetpack' ),
),
array(
'id' => 'wcj_product_input_fields_type_checkbox_default_' . $this->scope . '_',
'title' => __( 'If checkbox is selected, set default value here', 'woocommerce-jetpack' ),
'short_title' => __( 'Checkbox: Default', 'woocommerce-jetpack' ),
'type' => 'select',
'default' => 'no',
'options' => array(
'no' => __( 'Not Checked', 'woocommerce-jetpack' ),
'yes' => __( 'Checked', 'woocommerce-jetpack' ),
),
),
array(
'id' => 'wcj_product_input_fields_type_file_accept_' . $this->scope . '_',
'title' => __( 'If file is selected, set accepted file types here. E.g.: ".jpg,.jpeg,.png". Leave blank to accept all files', 'woocommerce-jetpack' )
. '. ' . __( 'Visit <a href="https://www.w3schools.com/tags/att_input_accept.asp" target="_blank">documentation on input accept attribute</a> for valid option formats', 'woocommerce-jetpack' ),
'short_title' => __( 'File: Accepted types', 'woocommerce-jetpack' ),
'type' => 'text',
'default' => __( '.jpg,.jpeg,.png', 'woocommerce-jetpack' ),
),
array(
'id' => 'wcj_product_input_fields_type_file_max_size_' . $this->scope . '_',
'title' => __( 'If file is selected, set max file size here. Set to zero to accept all files', 'woocommerce-jetpack' ),
'short_title' => __( 'File: Max size', 'woocommerce-jetpack' ),
'type' => 'number',
'default' => 0,
),
array(
'id' => 'wcj_product_input_fields_type_datepicker_format_' . $this->scope . '_',
'title' => __( 'If datepicker/weekpicker is selected, set date format here. Visit <a href="https://codex.wordpress.org/Formatting_Date_and_Time" target="_blank">documentation on date and time formatting</a> for valid date formats', 'woocommerce-jetpack' ),
'desc_tip' => __( 'Leave blank to use your current WordPress format', 'woocommerce-jetpack' ) . ': ' . get_option( 'date_format' ),
'short_title' => __( 'Datepicker/Weekpicker: Date format', 'woocommerce-jetpack' ),
'type' => 'text',
'default' => '',
),
array(
'id' => 'wcj_product_input_fields_type_datepicker_mindate_' . $this->scope . '_',
'title' => __( 'If datepicker/weekpicker is selected, set min date (in days) here', 'woocommerce-jetpack' ),
'short_title' => __( 'Datepicker/Weekpicker: Min date', 'woocommerce-jetpack' ),
'type' => 'number',
'default' => -365,
),
array(
'id' => 'wcj_product_input_fields_type_datepicker_maxdate_' . $this->scope . '_',
'title' => __( 'If datepicker/weekpicker is selected, set max date (in days) here', 'woocommerce-jetpack' ),
'short_title' => __( 'Datepicker/Weekpicker: Max date', 'woocommerce-jetpack' ),
'type' => 'number',
'default' => 365,
),
array(
'id' => 'wcj_product_input_fields_type_datepicker_changeyear_' . $this->scope . '_',
'title' => __( 'If datepicker/weekpicker is selected, set if you want to add year selector', 'woocommerce-jetpack' ),
'short_title' => __( 'Datepicker/Weekpicker: Change year', 'woocommerce-jetpack' ),
'type' => 'checkbox',
'default' => 'no',
),
array(
'id' => 'wcj_product_input_fields_type_datepicker_yearrange_' . $this->scope . '_',
'title' => __( 'If datepicker/weekpicker is selected, and year selector is enabled, set year range here', 'woocommerce-jetpack' ),
'short_title' => __( 'Datepicker/Weekpicker: Year range', 'woocommerce-jetpack' ),
// 'desc_tip' => __( 'The range of years displayed in the year drop-down: either relative to today\'s year ("-nn:+nn"), relative to the currently selected year ("c-nn:c+nn"), absolute ("nnnn:nnnn"), or combinations of these formats ("nnnn:-nn"). Note that this option only affects what appears in the drop-down, to restrict which dates may be selected use the minDate and/or maxDate options.', 'woocommerce-jetpack' ),
'type' => 'text',
'default' => 'c-10:c+10',
),
array(
'id' => 'wcj_product_input_fields_type_datepicker_firstday_' . $this->scope . '_',
'title' => __( 'If datepicker/weekpicker is selected, set first week day here', 'woocommerce-jetpack' ),
'short_title' => __( 'Datepicker/Weekpicker: First week day', 'woocommerce-jetpack' ),
'type' => 'select',
'default' => 0,
'options' => array(
__( 'Sunday', 'woocommerce-jetpack' ),
__( 'Monday', 'woocommerce-jetpack' ),
__( 'Tuesday', 'woocommerce-jetpack' ),
__( 'Wednesday', 'woocommerce-jetpack' ),
__( 'Thursday', 'woocommerce-jetpack' ),
__( 'Friday', 'woocommerce-jetpack' ),
__( 'Saturday', 'woocommerce-jetpack' ),
),
),
array(
'id' => 'wcj_product_input_fields_type_timepicker_format_' . $this->scope . '_',
'title' => __( 'If timepicker is selected, set time format here. Visit <a href="http://timepicker.co/options/" target="_blank">timepicker options page</a> for valid time formats', 'woocommerce-jetpack' ),
'short_title' => __( 'Timepicker: Time format', 'woocommerce-jetpack' ),
'type' => 'text',
'default' => 'hh:mm p',
),
array(
'id' => 'wcj_product_input_fields_type_timepicker_mintime_' . $this->scope . '_',
'title' => __( 'If timepicker is selected, set min time here. Visit <a href="http://timepicker.co/options/" target="_blank">timepicker options page</a> for valid option formats', 'woocommerce-jetpack' ),
'short_title' => __( 'Timepicker: Min Time', 'woocommerce-jetpack' ),
'type' => 'text',
'default' => '',
),
array(
'id' => 'wcj_product_input_fields_type_timepicker_maxtime_' . $this->scope . '_',
'title' => __( 'If timepicker is selected, set max time here. Visit <a href="http://timepicker.co/options/" target="_blank">timepicker options page</a> for valid option formats', 'woocommerce-jetpack' ),
'short_title' => __( 'Timepicker: Max Time', 'woocommerce-jetpack' ),
'type' => 'text',
'default' => '',
),
array(
'id' => 'wcj_product_input_fields_type_timepicker_interval_' . $this->scope . '_',
'title' => __( 'If timepicker is selected, set interval (in minutes) here', 'woocommerce-jetpack' ),
'short_title' => __( 'Timepicker: Interval', 'woocommerce-jetpack' ),
'type' => 'number',
'default' => 15,
),
array(
'id' => 'wcj_product_input_fields_type_select_options_' . $this->scope . '_',
'title' => __( 'If select/radio is selected, set options here. One option per line', 'woocommerce-jetpack' ),
'short_title' => __( 'Select/Radio: Options', 'woocommerce-jetpack' ),
'type' => 'textarea',
'default' => '',
'css' => 'height:200px;',
),
);