Enabled product bundles
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce Add to Cart per Category
|
||||
*
|
||||
* @version 2.2.6
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Add_To_Cart_Per_Category' ) ) :
|
||||
|
||||
class WCJ_Add_To_Cart_Per_Category {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
function __construct() {
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_per_category_enabled' ) ) {
|
||||
add_filter( 'woocommerce_product_single_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_single' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_archive' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_add_to_cart_button_text_single.
|
||||
*/
|
||||
function change_add_to_cart_button_text_single( $add_to_cart_text ) {
|
||||
return $this->change_add_to_cart_button_text( $add_to_cart_text, 'single' );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_add_to_cart_button_text_archive.
|
||||
*/
|
||||
function change_add_to_cart_button_text_archive( $add_to_cart_text ) {
|
||||
return $this->change_add_to_cart_button_text( $add_to_cart_text, 'archive' );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_add_to_cart_button_text.
|
||||
*
|
||||
* @version 2.2.6
|
||||
*/
|
||||
function change_add_to_cart_button_text( $add_to_cart_text, $single_or_archive ) {
|
||||
$product_categories = get_the_terms( get_the_ID(), 'product_cat' );
|
||||
if ( empty( $product_categories ) ) return $add_to_cart_text;
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_add_to_cart_per_category_total_groups_number', 1 ) ); $i++ ) {
|
||||
if ( 'yes' !== get_option( 'wcj_add_to_cart_per_category_enabled_group_' . $i ) ) continue;
|
||||
$categories = get_option( 'wcj_add_to_cart_per_category_ids_group_' . $i );
|
||||
if ( empty( $categories ) ) continue;
|
||||
foreach ( $product_categories as $product_category ) {
|
||||
foreach ( $categories as $category ) {
|
||||
if ( $product_category->term_id == $category ) {
|
||||
return get_option( 'wcj_add_to_cart_per_category_text_' . $single_or_archive . '_group_' . $i, $add_to_cart_text );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $add_to_cart_text;
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Add_To_Cart_Per_Category();
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Add to Cart Button Labels - Per Product Type
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Add_To_Cart_Per_Product_Type' ) ) :
|
||||
|
||||
class WCJ_Add_To_Cart_Per_Product_Type {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function __construct() {
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_text_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_product_single_add_to_cart_text', array( $this, 'custom_add_to_cart_button_text' ), 100 );
|
||||
add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'custom_add_to_cart_button_text' ), 100 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* custom_add_to_cart_button_text.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @todo (maybe) add checkbox options to enable/disable custom labels for each product type (or even for each label)
|
||||
*/
|
||||
function custom_add_to_cart_button_text( $add_to_cart_text ) {
|
||||
|
||||
global $woocommerce, $product;
|
||||
|
||||
if ( ! $product ) {
|
||||
return $add_to_cart_text;
|
||||
}
|
||||
|
||||
$product_type = ( WCJ_IS_WC_VERSION_BELOW_3 ? $product->product_type : $product->get_type() );
|
||||
if ( ! in_array( $product_type, array( 'external', 'grouped', 'simple', 'variable' ) ) ) {
|
||||
$product_type = 'other';
|
||||
}
|
||||
|
||||
$single_or_archive = ( 'woocommerce_product_single_add_to_cart_text' == current_filter() ? 'single' : 'archives' );
|
||||
|
||||
// Already in cart
|
||||
if ( '' != ( $text_already_in_cart = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_in_cart_' . $product_type, '' ) ) && isset( $woocommerce->cart ) ) {
|
||||
foreach( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
|
||||
$_product = $values['data'];
|
||||
if( get_the_ID() == wcj_get_product_id_or_variation_parent_id( $_product ) ) {
|
||||
return do_shortcode( $text_already_in_cart );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// On sale
|
||||
if ( '' != ( $text_on_sale = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_sale_' . $product_type, '' ) ) && $product->is_on_sale() ) {
|
||||
return do_shortcode( $text_on_sale );
|
||||
}
|
||||
|
||||
// Empty price
|
||||
if ( '' != ( $text_on_no_price = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_no_price_' . $product_type, '' ) ) && '' === $product->get_price() ) {
|
||||
return do_shortcode( $text_on_no_price );
|
||||
}
|
||||
|
||||
// Free (i.e. zero price)
|
||||
if ( '' != ( $text_on_zero_price = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_zero_price_' . $product_type, '' ) ) && 0 == $product->get_price() ) {
|
||||
return do_shortcode( $text_on_zero_price );
|
||||
}
|
||||
|
||||
// General
|
||||
if ( '' != ( $text_general = get_option( 'wcj_add_to_cart_text_on_' . $single_or_archive . '_' . $product_type, '' ) ) ) {
|
||||
return do_shortcode( $text_general );
|
||||
}
|
||||
|
||||
// Default
|
||||
return $add_to_cart_text;
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Add_To_Cart_Per_Product_Type();
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce Add to Cart per Product
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Add_To_Cart_Per_Product' ) ) :
|
||||
|
||||
class WCJ_Add_To_Cart_Per_Product {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
function __construct() {
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_per_product_enabled' ) ) {
|
||||
add_filter( 'woocommerce_product_single_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_single' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'change_add_to_cart_button_text_archive' ), PHP_INT_MAX );
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_custom_add_to_cart_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_custom_add_to_cart_meta_box' ), 100, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_add_to_cart_button_text_single.
|
||||
*/
|
||||
function change_add_to_cart_button_text_single( $add_to_cart_text ) {
|
||||
return $this->change_add_to_cart_button_text( $add_to_cart_text, 'single' );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_add_to_cart_button_text_archive.
|
||||
*/
|
||||
function change_add_to_cart_button_text_archive( $add_to_cart_text ) {
|
||||
return $this->change_add_to_cart_button_text( $add_to_cart_text, 'archive' );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_add_to_cart_button_text.
|
||||
*
|
||||
* @version 2.7.0
|
||||
*/
|
||||
function change_add_to_cart_button_text( $add_to_cart_text, $single_or_archive ) {
|
||||
global $product;
|
||||
if ( ! $product ) {
|
||||
return $add_to_cart_text;
|
||||
}
|
||||
$local_custom_add_to_cart_option_id = 'wcj_custom_add_to_cart_local_' . $single_or_archive;
|
||||
$local_custom_add_to_cart_option_value = get_post_meta( wcj_get_product_id_or_variation_parent_id( $product ), '_' . $local_custom_add_to_cart_option_id, true );
|
||||
if ( '' != $local_custom_add_to_cart_option_value ) {
|
||||
return $local_custom_add_to_cart_option_value;
|
||||
}
|
||||
return $add_to_cart_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* save_custom_add_to_cart_meta_box.
|
||||
*/
|
||||
function save_custom_add_to_cart_meta_box( $post_id, $post ) {
|
||||
// Check that we are saving with custom add to cart metabox displayed.
|
||||
if ( ! isset( $_POST['woojetpack_custom_add_to_cart_save_post'] ) ) {
|
||||
return;
|
||||
}
|
||||
$option_name = 'wcj_custom_add_to_cart_local_' . 'single';
|
||||
update_post_meta( $post_id, '_' . $option_name, $_POST[ $option_name ] );
|
||||
$option_name = 'wcj_custom_add_to_cart_local_' . 'archive';
|
||||
update_post_meta( $post_id, '_' . $option_name, $_POST[ $option_name ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_add_to_cart_meta_box.
|
||||
*
|
||||
* @version 2.4.8
|
||||
*/
|
||||
function add_custom_add_to_cart_meta_box() {
|
||||
add_meta_box(
|
||||
'wc-jetpack-custom-add-to-cart',
|
||||
__( 'Booster: Custom Add to Cart', 'woocommerce-jetpack' ),
|
||||
array( $this, 'create_custom_add_to_cart_meta_box' ),
|
||||
'product',
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_custom_add_to_cart_meta_box.
|
||||
*/
|
||||
function create_custom_add_to_cart_meta_box() {
|
||||
|
||||
$current_post_id = get_the_ID();
|
||||
|
||||
$options = array(
|
||||
'single' => __( 'Single product view', 'woocommerce-jetpack' ),
|
||||
'archive' => __( 'Product category (archive) view', 'woocommerce-jetpack' ),
|
||||
);
|
||||
|
||||
$html = '<table style="width:50%;min-width:300px;">';
|
||||
foreach ( $options as $option_key => $option_desc ) {
|
||||
$option_type = 'textarea';
|
||||
if ( 'url' == $option_key )
|
||||
$option_type = 'text';
|
||||
$html .= '<tr>';
|
||||
$html .= '<th>' . $option_desc . '</th>';
|
||||
|
||||
$option_id = 'wcj_custom_add_to_cart_local_' . $option_key;
|
||||
$option_value = get_post_meta( $current_post_id, '_' . $option_id, true );
|
||||
|
||||
if ( 'textarea' === $option_type )
|
||||
$html .= '<td style="width:80%;">';
|
||||
else
|
||||
$html .= '<td>';
|
||||
//switch ( $option_type ) {
|
||||
//case 'number':
|
||||
//case 'text':
|
||||
// $html .= '<input style="width:100%;" type="' . $option_type . '" id="' . $option_id . '" name="' . $option_id . '" value="' . $option_value . '">';
|
||||
// break;
|
||||
//case 'textarea':
|
||||
$html .= '<textarea style="width:100%;" id="' . $option_id . '" name="' . $option_id . '">' . $option_value . '</textarea>';
|
||||
// break;
|
||||
//}
|
||||
$html .= '</td>';
|
||||
$html .= '</tr>';
|
||||
}
|
||||
$html .= '</table>';
|
||||
$html .= '<input type="hidden" name="woojetpack_custom_add_to_cart_save_post" value="woojetpack_custom_add_to_cart_save_post">';
|
||||
echo $html;
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Add_To_Cart_Per_Product();
|
||||
@@ -0,0 +1,563 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Settings
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 1.0.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WC_Settings_Jetpack' ) ) :
|
||||
|
||||
class WC_Settings_Jetpack extends WC_Settings_Page {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.0.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'jetpack';
|
||||
$this->label = __( 'Booster', 'woocommerce-jetpack' );
|
||||
|
||||
$this->cats = include( 'wcj-modules-cats.php' );
|
||||
|
||||
$this->custom_dashboard_modules = apply_filters( 'wcj_custom_dashboard_modules', array() );
|
||||
|
||||
add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
|
||||
add_action( 'woocommerce_settings_' . $this->id, array( $this, 'output' ) );
|
||||
add_action( 'woocommerce_settings_save_' . $this->id, array( $this, 'save' ) );
|
||||
add_action( 'woocommerce_sections_' . $this->id, array( $this, 'output_cats_submenu' ) );
|
||||
add_action( 'woocommerce_sections_' . $this->id, array( $this, 'output_sections_submenu' ) );
|
||||
|
||||
require_once( 'class-wcj-settings-custom-fields.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Output cats
|
||||
*
|
||||
* @version 2.7.0
|
||||
*/
|
||||
function output_cats_submenu() {
|
||||
$current_cat = empty( $_REQUEST['wcj-cat'] ) ? 'dashboard' : sanitize_title( $_REQUEST['wcj-cat'] );
|
||||
if ( empty( $this->cats ) ) {
|
||||
return;
|
||||
}
|
||||
echo '<ul class="subsubsub" style="text-transform: uppercase !important; font-weight: bold; margin-bottom: 10px !important;">';
|
||||
$array_keys = array_keys( $this->cats );
|
||||
foreach ( $this->cats as $id => $label_info ) {
|
||||
echo '<li><a href="' . admin_url( 'admin.php?page=wc-settings&tab=' . $this->id . '&wcj-cat=' . sanitize_title( $id ) ) . '" class="' . ( $current_cat == $id ? 'current' : '' ) . '">' . $label_info['label'] . '</a> ' . ( end( $array_keys ) == $id ? '' : '|' ) . ' </li>';
|
||||
}
|
||||
echo '</ul>' . '<br class="clear" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output sections (modules) sub menu
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @todo (maybe) for case insensitive sorting: `array_multisort( array_map( 'strtolower', $menu ), $menu );` instead of `asort( $menu );` (see http://php.net/manual/en/function.asort.php)
|
||||
*/
|
||||
function output_sections_submenu() {
|
||||
global $current_section;
|
||||
$sections = $this->get_sections();
|
||||
$current_cat = empty( $_REQUEST['wcj-cat'] ) ? 'dashboard' : sanitize_title( $_REQUEST['wcj-cat'] );
|
||||
if ( 'dashboard' === $current_cat ) {
|
||||
|
||||
// Counting modules
|
||||
$all = 0;
|
||||
$active = 0;
|
||||
foreach ( $this->module_statuses as $module_status ) {
|
||||
if ( isset( $module_status['id'] ) && isset( $module_status['default'] ) ) {
|
||||
if ( 'yes' === get_option( $module_status['id'], $module_status['default'] ) ) {
|
||||
$active++;
|
||||
} elseif ( wcj_is_module_deprecated( $module_status['id'], true ) ) {
|
||||
continue;
|
||||
}
|
||||
$all++;
|
||||
}
|
||||
}
|
||||
|
||||
$sections['alphabetically'] = __( 'Alphabetically', 'woocommerce-jetpack' ) . ' <span class="count">(' . $all . ')</span>';
|
||||
$sections['by_category'] = __( 'By Category', 'woocommerce-jetpack' ) . ' <span class="count">(' . $all . ')</span>';
|
||||
$sections['active'] = __( 'Active', 'woocommerce-jetpack' ) . ' <span class="count">(' . $active . ')</span>';
|
||||
$sections['manager'] = __( 'Manage Settings', 'woocommerce-jetpack' );
|
||||
if ( ! empty( $this->custom_dashboard_modules ) ) {
|
||||
foreach ( $this->custom_dashboard_modules as $custom_dashboard_module_id => $custom_dashboard_module_data ) {
|
||||
$sections[ $custom_dashboard_module_id ] = $custom_dashboard_module_data['title'];
|
||||
}
|
||||
}
|
||||
if ( '' == $current_section ) {
|
||||
$current_section = 'by_category';
|
||||
}
|
||||
}
|
||||
if ( ! empty( $this->cats[ $current_cat ]['all_cat_ids'] ) ) {
|
||||
foreach ( $sections as $id => $label ) {
|
||||
if ( ! in_array( $id, $this->cats[ $current_cat ]['all_cat_ids'] ) ) {
|
||||
unset( $sections[ $id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( empty( $sections ) || 1 === count( $sections ) ) {
|
||||
return;
|
||||
}
|
||||
foreach ( $this->cats[ $current_cat ]['all_cat_ids'] as $key => $id ) {
|
||||
if ( wcj_is_module_deprecated( $id, false, true ) ) {
|
||||
unset( $this->cats[ $current_cat ]['all_cat_ids'][ $key ] );
|
||||
}
|
||||
}
|
||||
$menu = array();
|
||||
foreach ( $this->cats[ $current_cat ]['all_cat_ids'] as $id ) {
|
||||
$menu[ $id ] = $sections[ $id ];
|
||||
}
|
||||
if ( 'dashboard' !== $current_cat && 'pdf_invoicing' !== $current_cat ) {
|
||||
asort( $menu );
|
||||
}
|
||||
$menu_links = array();
|
||||
foreach ( $menu as $id => $label ) {
|
||||
$url = admin_url( 'admin.php?page=wc-settings&tab=' . $this->id . '&wcj-cat=' . $current_cat . '§ion=' . sanitize_title( $id ) );
|
||||
$menu_links[] = '<a href="' . $url . '" class="' . ( $current_section == $id ? 'current' : '' ) . '">' . $label . '</a>';
|
||||
}
|
||||
echo '<ul class="subsubsub">' . '<li>' . implode( '</li> | <li>', $menu_links ) . '</li>' . '</ul>' . '<br class="clear" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* get_cat_by_section
|
||||
*/
|
||||
function get_cat_by_section( $section ) {
|
||||
foreach ( $this->cats as $id => $label_info ) {
|
||||
if ( ! empty( $label_info['all_cat_ids'] ) ) {
|
||||
if ( in_array( $section, $label_info['all_cat_ids'] ) ) {
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sections (modules)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_sections() {
|
||||
return apply_filters( 'wcj_settings_sections', array( '' => __( 'Dashboard', 'woocommerce-jetpack' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* active.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function active( $active ) {
|
||||
return ( 'yes' === $active ) ? 'active' : 'inactive';
|
||||
}
|
||||
|
||||
/**
|
||||
* is_dashboard_section.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function is_dashboard_section( $current_section ) {
|
||||
return in_array( $current_section, array_merge( array( '', 'alphabetically', 'by_category', 'active', 'manager' ), array_keys( $this->custom_dashboard_modules ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the settings.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @todo (maybe) admin_notices
|
||||
*/
|
||||
function output() {
|
||||
|
||||
global $current_section, $wcj_notice;
|
||||
|
||||
if ( '' != $wcj_notice ) {
|
||||
echo '<div id="wcj_message" class="updated"><p><strong>' . $wcj_notice . '</strong></p></div>';
|
||||
}
|
||||
|
||||
$is_dashboard = $this->is_dashboard_section( $current_section );
|
||||
|
||||
// Deprecated message
|
||||
if ( $replacement_module = wcj_is_module_deprecated( $current_section ) ) {
|
||||
echo '<div id="wcj_message" class="error">';
|
||||
echo '<p>';
|
||||
echo '<strong>';
|
||||
echo sprintf(
|
||||
__( 'Please note that current <em>%s</em> module is deprecated and will be removed in future updates. Please use <em>%s</em> module instead.', 'woocommerce-jetpack' ),
|
||||
WCJ()->modules[ $current_section ]->short_desc,
|
||||
'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $replacement_module['cat'] . '§ion=' . $replacement_module['module'] ) . '">' .
|
||||
$replacement_module['title'] . '</a>'
|
||||
);
|
||||
echo ' <span style="color:red;">' . __( 'Module will be removed from the module\'s list as soon as you disable it.', 'woocommerce-jetpack' ) . '</span>';
|
||||
echo '</strong>';
|
||||
echo '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
// "Under development" message
|
||||
if ( isset( WCJ()->modules[ $current_section ]->dev ) && true === WCJ()->modules[ $current_section ]->dev ) {
|
||||
echo '<div id="wcj_message" class="error">';
|
||||
echo '<p>';
|
||||
echo '<strong>';
|
||||
echo sprintf( __( 'Please note that <em>%s</em> module is currently under development. Until stable module version is released, options can be changed or some options can be moved to paid plugin version.', 'woocommerce-jetpack' ), WCJ()->modules[ $current_section ]->short_desc );
|
||||
echo '</strong>';
|
||||
echo '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
if ( 'yes' === get_option( 'wcj_admin_tools_enabled', 'no' ) && 'yes' === get_option( 'wcj_debuging_enabled', 'no' ) ) {
|
||||
// Breadcrumbs
|
||||
$breadcrumbs_html = '';
|
||||
$breadcrumbs_html .= '<p>';
|
||||
$breadcrumbs_html .= '<code>';
|
||||
$breadcrumbs_html .= __( 'WooCommerce', 'woocommerce-jetpack' );
|
||||
$breadcrumbs_html .= ' > ';
|
||||
$breadcrumbs_html .= __( 'Settings', 'woocommerce-jetpack' );
|
||||
$breadcrumbs_html .= ' > ';
|
||||
$breadcrumbs_html .= __( 'Booster', 'woocommerce-jetpack' );
|
||||
$breadcrumbs_html .= ' > ';
|
||||
foreach ( $this->cats as $id => $label_info ) {
|
||||
if ( $this->get_cat_by_section( $current_section ) === $id ) {
|
||||
$breadcrumbs_html .= $label_info['label'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( $is_dashboard && isset( $_GET['wcj-cat'] ) && 'dashboard' != $_GET['wcj-cat'] ) {
|
||||
$breadcrumbs_html .= $this->cats[ $_GET['wcj-cat'] ]['label'];
|
||||
}
|
||||
if ( ! $is_dashboard ) {
|
||||
$breadcrumbs_html .= ' > ';
|
||||
$sections = $this->get_sections();
|
||||
$breadcrumbs_html .= $sections[ $current_section ];
|
||||
}
|
||||
$breadcrumbs_html .= '</code>';
|
||||
$breadcrumbs_html .= '</p>';
|
||||
echo $breadcrumbs_html;
|
||||
}
|
||||
|
||||
$settings = $this->get_settings( $current_section );
|
||||
|
||||
if ( ! $is_dashboard ) {
|
||||
WC_Admin_Settings::output_fields( $settings );
|
||||
} else {
|
||||
$this->output_dashboard( $current_section );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* output_dashboard.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function output_dashboard( $current_section ) {
|
||||
|
||||
if ( '' == $current_section ) {
|
||||
$current_section = 'by_category';
|
||||
}
|
||||
|
||||
$the_settings = $this->get_settings();
|
||||
|
||||
echo '<h3>' . $the_settings[0]['title'] . '</h3>';
|
||||
if ( isset( $this->custom_dashboard_modules[ $current_section ] ) ) {
|
||||
echo '<p>' . $this->custom_dashboard_modules[ $current_section ]['desc'] . '</p>';
|
||||
} elseif ( 'manager' != $current_section ) {
|
||||
echo '<p>' . $the_settings[0]['desc'] . '</p>';
|
||||
} else {
|
||||
echo '<p>' . __( 'This section lets you export, import or reset all Booster\'s modules settings.', 'woocommerce-jetpack' ) . '</p>';
|
||||
}
|
||||
|
||||
if ( 'alphabetically' === $current_section ) {
|
||||
$this->output_dashboard_modules( $the_settings );
|
||||
} elseif ( 'by_category' === $current_section ) {
|
||||
foreach ( $this->cats as $cat_id => $cat_label_info ) {
|
||||
if ( 'dashboard' === $cat_id ) {
|
||||
continue;
|
||||
}
|
||||
if ( isset( $_GET['wcj-cat'] ) && 'dashboard' != $_GET['wcj-cat'] ) {
|
||||
if ( $cat_id != $_GET['wcj-cat'] ) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
echo '<h4>' . $cat_label_info['label'] . '</h4>';
|
||||
}
|
||||
$this->output_dashboard_modules( $the_settings, $cat_id );
|
||||
}
|
||||
} elseif ( 'active' === $current_section ) {
|
||||
$this->output_dashboard_modules( $the_settings, 'active_modules_only' );
|
||||
} elseif ( 'manager' === $current_section ) {
|
||||
$table_data = array(
|
||||
array(
|
||||
'<button style="width:100px;" class="button-primary" type="submit" name="booster_export_settings">' . __( 'Export', 'woocommerce-jetpack' ) . '</button>',
|
||||
'<em>' . __( 'Export all Booster\'s options to a file.', 'woocommerce-jetpack' ) . '</em>',
|
||||
),
|
||||
array(
|
||||
'<button style="width:100px;" class="button-primary" type="submit" name="booster_import_settings">' . __( 'Import', 'woocommerce-jetpack' ) . '</button>' .
|
||||
' ' . '<input type="file" name="booster_import_settings_file">',
|
||||
'<em>' . __( 'Import all Booster\'s options from a file.', 'woocommerce-jetpack' ) . '</em>',
|
||||
),
|
||||
array(
|
||||
'<button style="width:100px;" class="button-primary" type="submit" name="booster_reset_settings"' .
|
||||
wcj_get_js_confirmation( __( 'This will reset settings to defaults for all Booster modules. Are you sure?', 'woocommerce-jetpack' ) ) . '>' .
|
||||
__( 'Reset', 'woocommerce-jetpack' ) . '</button>',
|
||||
'<em>' . __( 'Reset all Booster\'s options.', 'woocommerce-jetpack' ) . '</em>',
|
||||
),
|
||||
array(
|
||||
'<button style="width:100px;" class="button-primary" type="submit" name="booster_reset_settings_meta"' .
|
||||
wcj_get_js_confirmation( __( 'This will delete all Booster meta. Are you sure?', 'woocommerce-jetpack' ) ) . '>' .
|
||||
__( 'Reset meta', 'woocommerce-jetpack' ) . '</button>',
|
||||
'<em>' . __( 'Reset all Booster\'s meta.', 'woocommerce-jetpack' ) . '</em>',
|
||||
),
|
||||
);
|
||||
$manager_settings = $this->get_manager_settings();
|
||||
foreach ( $manager_settings as $manager_settings_field ) {
|
||||
$table_data[] = array(
|
||||
'<label for="' . $manager_settings_field['id'] . '">' .
|
||||
'<input name="' . $manager_settings_field['id'] . '" id="' . $manager_settings_field['id'] . '" type="' . $manager_settings_field['type'] . '"' .
|
||||
' class="" value="1" ' . checked( get_option( $manager_settings_field['id'], $manager_settings_field['default'] ), 'yes', false ) . '>' .
|
||||
' ' . '<strong>' . $manager_settings_field['title'] . '</strong>' .
|
||||
'</label>',
|
||||
'<em>' . $manager_settings_field['desc'] . '</em>',
|
||||
);
|
||||
}
|
||||
echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'none' ) );
|
||||
}
|
||||
|
||||
if ( isset( $this->custom_dashboard_modules[ $current_section ] ) ) {
|
||||
$table_data = array();
|
||||
foreach ( $this->custom_dashboard_modules[ $current_section ]['settings'] as $_settings ) {
|
||||
$table_data[] = array(
|
||||
$_settings['title'],
|
||||
'<label for="' . $_settings['id'] . '">' .
|
||||
'<input name="' . $_settings['id'] .
|
||||
'" id="' . $_settings['id'] .
|
||||
'" type="' . $_settings['type'] .
|
||||
'" class="' . $_settings['class'] .
|
||||
'" value="' . get_option( $_settings['id'], $_settings['default'] )
|
||||
. '">' . ' ' . '<em>' . $_settings['desc'] . '</em>' .
|
||||
'</label>',
|
||||
);
|
||||
}
|
||||
echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'vertical' ) );
|
||||
}
|
||||
|
||||
$plugin_data = get_plugin_data( WCJ_PLUGIN_FILE );
|
||||
$plugin_title = ( isset( $plugin_data['Name'] ) ? '[' . $plugin_data['Name'] . '] ' : '' );
|
||||
echo '<p style="text-align:right;color:gray;font-size:x-small;font-style:italic;">' . $plugin_title .
|
||||
__( 'Version', 'woocommerce-jetpack' ) . ': ' . get_option( WCJ_VERSION_OPTION, 'N/A' ) . '</p>';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* compare_for_usort.
|
||||
*/
|
||||
private function compare_for_usort( $a, $b ) {
|
||||
return strcmp( $a['title'], $b['title'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* output_dashboard_modules.
|
||||
*
|
||||
* @version 3.3.0
|
||||
*/
|
||||
function output_dashboard_modules( $settings, $cat_id = '' ) {
|
||||
?>
|
||||
<table class="wp-list-table widefat plugins">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" id="cb" class="manage-column column-cb check-column" style=""><label class="screen-reader-text" for="cb-select-all-1"><?php _e( 'Select All', 'woocommerce-jetpack' ); ?></label><input id="cb-select-all-1" type="checkbox" style="margin-top:15px;"></th>
|
||||
<th scope="col" id="name" class="manage-column column-name" style=""><?php _e( 'Module', 'woocommerce-jetpack' ); ?></th>
|
||||
<th scope="col" id="description" class="manage-column column-description" style=""><?php _e( 'Description', 'woocommerce-jetpack' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th scope="col" class="manage-column column-cb check-column" style=""><label class="screen-reader-text" for="cb-select-all-2"><?php _e( 'Select All', 'woocommerce-jetpack' ); ?></label><input id="cb-select-all-2" type="checkbox" style="margin-top:15px;"></th>
|
||||
<th scope="col" class="manage-column column-name" style=""><?php _e( 'Module', 'woocommerce-jetpack' ); ?></th>
|
||||
<th scope="col" class="manage-column column-description" style=""><?php _e( 'Description', 'woocommerce-jetpack' ); ?></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tbody id="the-list"><?php
|
||||
$html = '';
|
||||
usort( $settings, array( $this, 'compare_for_usort' ) );
|
||||
$total_modules = 0;
|
||||
foreach ( $settings as $the_feature ) {
|
||||
if ( 'checkbox' !== $the_feature['type'] ) {
|
||||
continue;
|
||||
}
|
||||
$section = $the_feature['id'];
|
||||
$section = str_replace( 'wcj_', '', $section );
|
||||
$section = str_replace( '_enabled', '', $section );
|
||||
if ( wcj_is_module_deprecated( $section, false, true ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( '' != $cat_id ) {
|
||||
if ( 'active_modules_only' === $cat_id ) {
|
||||
if ( 'no' === get_option( $the_feature['id'], 'no' ) ) {
|
||||
continue;
|
||||
}
|
||||
} elseif ( $cat_id != $this->get_cat_by_section( $section ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$total_modules++;
|
||||
$html .= '<tr id="' . $the_feature['id'] . '" ' . 'class="' . $this->active( get_option( $the_feature['id'] ) ) . '">';
|
||||
$html .= '<th scope="row" class="check-column">';
|
||||
$html .= '<label class="screen-reader-text" for="' . $the_feature['id'] . '">' . $the_feature['desc'] . '</label>';
|
||||
$html .= '<input type="checkbox" name="' . $the_feature['id'] . '" value="1" id="' . $the_feature['id'] . '" ' . checked( get_option( $the_feature['id'] ), 'yes', false ) . '>';
|
||||
$html .= '</th>';
|
||||
$html .= '<td class="plugin-title">' . '<strong>' . $the_feature['title'] . '</strong>';
|
||||
$html .= '<div class="row-actions visible">';
|
||||
$html .= '<span class="0"><a href="' . admin_url() . 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $this->get_cat_by_section( $section ) . '§ion=' . $section . '">' . __( 'Settings', 'woocommerce' ) . '</a></span>';
|
||||
if ( isset( $the_feature['wcj_link'] ) && '' != $the_feature['wcj_link'] ) {
|
||||
$html .= ' | <span class="0"><a href="' . $the_feature['wcj_link'] . '?utm_source=module_documentation&utm_medium=dashboard_link&utm_campaign=booster_documentation" target="_blank">' . __( 'Documentation', 'woocommerce' ) . '</a></span>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
$html .= '</td>';
|
||||
$html .= '<td class="column-description desc">';
|
||||
$html .= '<div class="plugin-description"><p>' . ( ( isset( $the_feature['wcj_desc'] ) ) ? $the_feature['wcj_desc'] : $the_feature['desc_tip'] ) . '</p></div>';
|
||||
$html .= '</td>';
|
||||
$html .= '</tr>';
|
||||
}
|
||||
echo $html;
|
||||
if ( 0 == $total_modules && 'active_modules_only' === $cat_id ) {
|
||||
echo '<tr><td colspan="3">' . '<em>' . __( 'No active modules found.', 'woocommerce-jetpack' ) . '</em>' . '</td></tr>';
|
||||
}
|
||||
?></tbody>
|
||||
</table><p style="color:gray;font-size:x-small;font-style:italic;"><?php echo __( 'Total Modules:' ) . ' ' . $total_modules; ?></p><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings.
|
||||
*
|
||||
* @version 3.6.0
|
||||
*/
|
||||
function save() {
|
||||
global $current_section;
|
||||
$settings = $this->get_settings( $current_section );
|
||||
WC_Admin_Settings::save_fields( $settings );
|
||||
add_action( 'admin_notices', array( $this, 'booster_message_global' ) );
|
||||
do_action( 'woojetpack_after_settings_save', $this->get_sections(), $current_section );
|
||||
}
|
||||
|
||||
/**
|
||||
* booster_message_global.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function booster_message_global() {
|
||||
if ( '' != ( $message = apply_filters( 'booster_message', '', 'global' ) ) ) {
|
||||
echo $message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_manager_settings.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.6.0
|
||||
* @return array
|
||||
*/
|
||||
function get_manager_settings() {
|
||||
return array(
|
||||
array(
|
||||
'title' => __( 'Autoload Booster\'s Options', 'woocommerce-jetpack' ),
|
||||
'type' => 'checkbox',
|
||||
'desc' => __( 'Choose if you want Booster\'s options to be autoloaded when calling add_option. After saving this option, you need to Reset all Booster\'s settings. Leave default value (i.e. Enabled) if not sure.', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_autoload_options',
|
||||
'default' => 'yes',
|
||||
),
|
||||
array(
|
||||
'title' => __( 'Use List Instead of Comma Separated Text for Products in Settings', 'woocommerce-jetpack' ),
|
||||
'type' => 'checkbox',
|
||||
'desc' => sprintf( __( 'Supported modules: %s.', 'woocommerce-jetpack' ), implode( ', ', array(
|
||||
__( 'Gateways per Product or Category', 'woocommerce-jetpack' ),
|
||||
__( 'Global Discount', 'woocommerce-jetpack' ),
|
||||
__( 'Product Info', 'woocommerce-jetpack' ),
|
||||
__( 'Product Input Fields', 'woocommerce-jetpack' ),
|
||||
__( 'Products XML', 'woocommerce-jetpack' ),
|
||||
__( 'Related Products', 'woocommerce-jetpack' ),
|
||||
) ) ),
|
||||
'id' => 'wcj_list_for_products',
|
||||
'default' => 'yes',
|
||||
),
|
||||
array(
|
||||
'title' => __( 'Use List Instead of Comma Separated Text for Products Categories in Settings', 'woocommerce-jetpack' ),
|
||||
'type' => 'checkbox',
|
||||
'desc' => sprintf( __( 'Supported modules: %s.', 'woocommerce-jetpack' ), implode( ', ', array(
|
||||
__( 'Product Info', 'woocommerce-jetpack' ),
|
||||
) ) ),
|
||||
'id' => 'wcj_list_for_products_cats',
|
||||
'default' => 'yes',
|
||||
),
|
||||
array(
|
||||
'title' => __( 'Use List Instead of Comma Separated Text for Products Tags in Settings', 'woocommerce-jetpack' ),
|
||||
'type' => 'checkbox',
|
||||
'desc' => sprintf( __( 'Supported modules: %s.', 'woocommerce-jetpack' ), implode( ', ', array(
|
||||
__( 'Product Info', 'woocommerce-jetpack' ),
|
||||
) ) ),
|
||||
'id' => 'wcj_list_for_products_tags',
|
||||
'default' => 'yes',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings array
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @return array
|
||||
*/
|
||||
function get_settings( $current_section = '' ) {
|
||||
if ( ! $this->is_dashboard_section( $current_section ) ) {
|
||||
return apply_filters( 'wcj_settings_' . $current_section, array() );
|
||||
} elseif ( 'manager' === $current_section ) {
|
||||
return $this->get_manager_settings();
|
||||
} elseif ( isset( $this->custom_dashboard_modules[ $current_section ] ) ) {
|
||||
return $this->custom_dashboard_modules[ $current_section ]['settings'];
|
||||
} else {
|
||||
$cat_id = ( isset( $_GET['wcj-cat'] ) && '' != $_GET['wcj-cat'] ) ? $_GET['wcj-cat'] : 'dashboard';
|
||||
$settings[] = array(
|
||||
'title' => __( 'Booster for WooCommerce', 'woocommerce-jetpack' ) . ' - ' . $this->cats[ $cat_id ]['label'],
|
||||
'type' => 'title',
|
||||
'desc' => $this->cats[ $cat_id ]['desc'],
|
||||
'id' => 'wcj_' . $cat_id . '_options',
|
||||
);
|
||||
if ( 'dashboard' === $cat_id ) {
|
||||
$settings = array_merge( $settings, $this->module_statuses );
|
||||
} else {
|
||||
$cat_module_statuses = array();
|
||||
foreach ( $this->module_statuses as $module_status ) {
|
||||
$section = $module_status['id'];
|
||||
$section = str_replace( 'wcj_', '', $section );
|
||||
$section = str_replace( '_enabled', '', $section );
|
||||
if ( $cat_id === $this->get_cat_by_section( $section ) ) {
|
||||
$cat_module_statuses[] = $module_status;
|
||||
}
|
||||
}
|
||||
$settings = array_merge( $settings, $cat_module_statuses );
|
||||
}
|
||||
$settings[] = array(
|
||||
'type' => 'sectionend',
|
||||
'id' => 'wcj_' . $cat_id . '_options',
|
||||
'title' => '', // for usort
|
||||
);
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_module_statuses
|
||||
*/
|
||||
function add_module_statuses( $statuses ) {
|
||||
$this->module_statuses = $statuses;
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WC_Settings_Jetpack();
|
||||
@@ -0,0 +1,332 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Settings Custom Fields
|
||||
*
|
||||
* @version 3.4.5
|
||||
* @since 2.8.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Settings_Custom_Fields' ) ) :
|
||||
|
||||
class WCJ_Settings_Custom_Fields {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
add_action( 'woocommerce_admin_field_wcj_save_settings_button', array( $this, 'output_wcj_save_settings_button' ) );
|
||||
add_action( 'woocommerce_admin_field_wcj_number_plus_checkbox_start', array( $this, 'output_wcj_number_plus_checkbox_start' ) );
|
||||
add_action( 'woocommerce_admin_field_wcj_number_plus_checkbox_end', array( $this, 'output_wcj_number_plus_checkbox_end' ) );
|
||||
add_filter( 'woocommerce_admin_settings_sanitize_option', array( $this, 'format_wcj_number_plus_checkbox_end' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'woocommerce_admin_field_custom_textarea', array( $this, 'output_custom_textarea' ) );
|
||||
add_filter( 'woocommerce_admin_settings_sanitize_option', array( $this, 'unclean_custom_textarea' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'woocommerce_admin_field_custom_number', array( $this, 'output_custom_number' ) );
|
||||
add_action( 'woocommerce_admin_field_custom_link', array( $this, 'output_custom_link' ) );
|
||||
add_action( 'woocommerce_admin_field_module_tools', array( $this, 'output_module_tools' ) );
|
||||
add_filter( 'woocommerce_admin_settings_sanitize_option', array( $this, 'maybe_unclean_field' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'woocommerce_admin_field_exchange_rate', array( $this, 'output_exchange_rate_settings_button' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* output_exchange_rate_settings_button.
|
||||
*
|
||||
* @version 3.4.5
|
||||
*/
|
||||
function output_exchange_rate_settings_button( $value ) {
|
||||
|
||||
$value['type'] = 'number';
|
||||
|
||||
$option_value = get_option( $value['id'], $value['default'] );
|
||||
|
||||
// Custom attribute handling
|
||||
$custom_attributes = array();
|
||||
if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
|
||||
foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
|
||||
$custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
|
||||
}
|
||||
} else {
|
||||
$custom_attributes = array( 'step="' . sprintf( "%.12f", 1 / pow( 10, 12 ) ) . '"', 'min="0"' );
|
||||
}
|
||||
$custom_attributes_button = array();
|
||||
if ( ! empty( $value['custom_attributes_button'] ) && is_array( $value['custom_attributes_button'] ) ) {
|
||||
foreach ( $value['custom_attributes_button'] as $attribute => $attribute_value ) {
|
||||
$custom_attributes_button[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
|
||||
}
|
||||
}
|
||||
$tip = '';
|
||||
$description = '';
|
||||
$exchange_rate_server = wcj_get_currency_exchange_rate_server_name( $value['custom_attributes_button']['currency_from'], $value['custom_attributes_button']['currency_to'] );
|
||||
$value_title = sprintf( __( 'Grab raw %s rate from %s.', 'woocommerce-jetpack' ), $value['value'], $exchange_rate_server ) .
|
||||
' ' . __( 'Doesn\'t apply rounding, offset etc.', 'woocommerce-jetpack' );
|
||||
?>
|
||||
<tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
|
||||
<?php echo $tip; ?>
|
||||
</th>
|
||||
<td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
|
||||
<input
|
||||
name="<?php echo esc_attr( $value['id'] ); ?>"
|
||||
id="<?php echo esc_attr( $value['id'] ); ?>"
|
||||
type="<?php echo esc_attr( $value['type'] ); ?>"
|
||||
style="<?php echo esc_attr( $value['css'] ); ?>"
|
||||
value="<?php echo esc_attr( $option_value ); ?>"
|
||||
class="<?php echo esc_attr( $value['class'] ); ?>"
|
||||
<?php echo implode( ' ', $custom_attributes ); ?>
|
||||
/>
|
||||
<input
|
||||
name="<?php echo esc_attr( $value['id'] . '_button' ); ?>"
|
||||
id="<?php echo esc_attr( $value['id'] . '_button' ); ?>"
|
||||
type="button"
|
||||
value="<?php echo esc_attr( $value['value'] ); ?>"
|
||||
title="<?php echo esc_attr( $value_title ); ?>"
|
||||
class="exchage_rate_button"
|
||||
<?php echo implode( ' ', $custom_attributes_button ); ?>
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_unclean_field.
|
||||
*
|
||||
* @version 3.1.3
|
||||
* @since 3.1.3
|
||||
*/
|
||||
function maybe_unclean_field( $value, $option, $raw_value ) {
|
||||
return ( isset( $option['wcj_raw'] ) && $option['wcj_raw'] ? $raw_value : $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* output_wcj_save_settings_button.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function output_wcj_save_settings_button( $value ) {
|
||||
// Output
|
||||
?><tr valign="top">
|
||||
<th scope="row" class="titledesc"></th>
|
||||
<td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
|
||||
<input name="save" class="button-primary woocommerce-save-button" type="submit" value="<?php echo esc_html( $value['title'] ); ?>">
|
||||
</td>
|
||||
</tr><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* format_wcj_number_plus_checkbox_end.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function format_wcj_number_plus_checkbox_end( $value, $option, $raw_value ) {
|
||||
return ( 'wcj_number_plus_checkbox_end' === $option['type'] ) ? ( '1' === $raw_value || 'yes' === $raw_value ? 'yes' : 'no' ) : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* output_wcj_number_plus_checkbox_start.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function output_wcj_number_plus_checkbox_start( $value ) {
|
||||
// Custom attribute handling
|
||||
$custom_attributes = array();
|
||||
if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
|
||||
foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
|
||||
$custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
|
||||
}
|
||||
}
|
||||
// Description handling
|
||||
$field_description = WC_Admin_Settings::get_field_description( $value );
|
||||
extract( $field_description );
|
||||
// Option value
|
||||
$option_value = WC_Admin_Settings::get_option( $value['id'], $value['default'] );
|
||||
// Output
|
||||
?><tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
|
||||
<?php echo $tooltip_html; ?>
|
||||
</th>
|
||||
<td class="forminp forminp-number-checkbox">
|
||||
<input
|
||||
name="<?php echo esc_attr( $value['id'] ); ?>"
|
||||
id="<?php echo esc_attr( $value['id'] ); ?>"
|
||||
type="number"
|
||||
style="<?php echo esc_attr( $value['css'] ); ?>"
|
||||
value="<?php echo esc_attr( $option_value ); ?>"
|
||||
class="<?php echo esc_attr( $value['class'] ); ?>"
|
||||
placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
|
||||
<?php echo implode( ' ', $custom_attributes ); ?>
|
||||
/> <?php echo $description . ' ';
|
||||
}
|
||||
|
||||
/**
|
||||
* output_wcj_number_plus_checkbox_end.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function output_wcj_number_plus_checkbox_end( $value ) {
|
||||
// Custom attribute handling
|
||||
$custom_attributes = array();
|
||||
if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
|
||||
foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
|
||||
$custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
|
||||
}
|
||||
}
|
||||
// Description handling
|
||||
$field_description = WC_Admin_Settings::get_field_description( $value );
|
||||
extract( $field_description );
|
||||
// Option value
|
||||
$option_value = WC_Admin_Settings::get_option( $value['id'], $value['default'] );
|
||||
// Output
|
||||
?><label for="<?php echo $value['id'] ?>">
|
||||
<input
|
||||
name="<?php echo esc_attr( $value['id'] ); ?>"
|
||||
id="<?php echo esc_attr( $value['id'] ); ?>"
|
||||
type="checkbox"
|
||||
class="<?php echo esc_attr( isset( $value['class'] ) ? $value['class'] : '' ); ?>"
|
||||
value="1"
|
||||
<?php checked( $option_value, 'yes' ); ?>
|
||||
<?php echo implode( ' ', $custom_attributes ); ?>
|
||||
/> <?php echo $description ?>
|
||||
</label> <?php echo $tooltip_html; ?>
|
||||
</td>
|
||||
</tr><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* unclean_custom_textarea.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function unclean_custom_textarea( $value, $option, $raw_value ) {
|
||||
return ( 'custom_textarea' === $option['type'] ) ? $raw_value : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* output_custom_textarea.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.2.6
|
||||
*/
|
||||
function output_custom_textarea( $value ) {
|
||||
$option_value = get_option( $value['id'], $value['default'] );
|
||||
$custom_attributes = ( isset( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) ?
|
||||
$value['custom_attributes'] : array();
|
||||
$description = ' <p class="description">' . $value['desc'] . '</p>';
|
||||
$tooltip_html = ( isset( $value['desc_tip'] ) && '' != $value['desc_tip'] ) ?
|
||||
'<span class="woocommerce-help-tip" data-tip="' . $value['desc_tip'] . '"></span>' : '';
|
||||
// Output
|
||||
?><tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
|
||||
<?php echo $tooltip_html; ?>
|
||||
</th>
|
||||
<td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
|
||||
<?php echo $description; ?>
|
||||
|
||||
<textarea
|
||||
name="<?php echo esc_attr( $value['id'] ); ?>"
|
||||
id="<?php echo esc_attr( $value['id'] ); ?>"
|
||||
style="<?php echo esc_attr( $value['css'] ); ?>"
|
||||
class="<?php echo esc_attr( $value['class'] ); ?>"
|
||||
placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
|
||||
<?php echo implode( ' ', $custom_attributes ); ?>
|
||||
><?php echo esc_textarea( $option_value ); ?></textarea>
|
||||
</td>
|
||||
</tr><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* output_module_tools.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.2.3
|
||||
*/
|
||||
function output_module_tools( $value ) {
|
||||
?><tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
|
||||
<span class="woocommerce-help-tip" data-tip="<?php echo __( 'To use tools, module must be enabled.', 'woocommerce-jetpack' ); ?>"></span>
|
||||
</th>
|
||||
<td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
|
||||
<?php if ( isset( $_GET['section'] ) ) do_action( 'wcj_module_tools_' . $_GET['section'] ); ?>
|
||||
</td>
|
||||
</tr><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* output_custom_link.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.2.8
|
||||
*/
|
||||
function output_custom_link( $value ) {
|
||||
$tooltip_html = ( isset( $value['desc_tip'] ) && '' != $value['desc_tip'] ) ?
|
||||
'<span class="woocommerce-help-tip" data-tip="' . $value['desc_tip'] . '"></span>' : '';
|
||||
?><tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label><?php echo $tooltip_html; ?>
|
||||
</th>
|
||||
<td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
|
||||
<?php echo $value['link']; ?>
|
||||
</td>
|
||||
</tr><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* output_custom_number.
|
||||
*
|
||||
* @version 2.5.5
|
||||
*/
|
||||
function output_custom_number( $value ) {
|
||||
$type = 'number';
|
||||
$option_value = get_option( $value['id'], $value['default'] );
|
||||
$tooltip_html = ( isset( $value['desc_tip'] ) && '' != $value['desc_tip'] ) ?
|
||||
'<span class="woocommerce-help-tip" data-tip="' . $value['desc_tip'] . '"></span>' : '';
|
||||
$description = ' <span class="description">' . $value['desc'] . '</span>';
|
||||
$save_button = apply_filters( 'booster_option', '',
|
||||
' <input name="save" class="button-primary" type="submit" value="' . __( 'Save changes', 'woocommerce' ) . '">' );
|
||||
// Custom attribute handling
|
||||
$custom_attributes = array();
|
||||
if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) {
|
||||
foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) {
|
||||
$custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
|
||||
}
|
||||
}
|
||||
// Output
|
||||
?><tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
|
||||
<?php echo $tooltip_html; ?>
|
||||
</th>
|
||||
<td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
|
||||
<input
|
||||
name="<?php echo esc_attr( $value['id'] ); ?>"
|
||||
id="<?php echo esc_attr( $value['id'] ); ?>"
|
||||
type="<?php echo esc_attr( $type ); ?>"
|
||||
style="<?php echo esc_attr( $value['css'] ); ?>"
|
||||
value="<?php echo esc_attr( $option_value ); ?>"
|
||||
class="<?php echo esc_attr( $value['class'] ); ?>"
|
||||
placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
|
||||
<?php echo implode( ' ', $custom_attributes ); ?>
|
||||
/><?php echo $save_button; ?><?php echo $description; ?>
|
||||
</td>
|
||||
</tr><?php
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Settings_Custom_Fields();
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Settings Manager - Import / Export / Reset Booster's settings
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.9.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Settings_Manager' ) ) :
|
||||
|
||||
class WCJ_Settings_Manager {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo add options to import/export selected modules only
|
||||
*/
|
||||
function __construct() {
|
||||
add_action( 'wp_loaded', array( $this, 'manage_options' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
/**
|
||||
* manage_options.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function manage_options() {
|
||||
if ( is_admin() ) {
|
||||
if ( ! function_exists( 'current_user_can' ) || ! current_user_can( 'manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
if ( isset( $_POST['booster_import_settings'] ) ) {
|
||||
$this->manage_options_import();
|
||||
}
|
||||
if ( isset( $_POST['booster_export_settings'] ) ) {
|
||||
$this->manage_options_export();
|
||||
}
|
||||
if ( isset( $_POST['booster_reset_settings'] ) ) {
|
||||
$this->manage_options_reset();
|
||||
}
|
||||
if ( isset( $_POST['booster_reset_settings_meta'] ) ) {
|
||||
$this->manage_options_reset_meta();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* manage_options_import.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function manage_options_import() {
|
||||
global $wcj_notice;
|
||||
if( ! isset( $_FILES['booster_import_settings_file']['tmp_name'] ) || '' == $_FILES['booster_import_settings_file']['tmp_name'] ) {
|
||||
$wcj_notice .= __( 'Please upload a file to import!', 'woocommerce-jetpack' );
|
||||
$import_settings = array();
|
||||
unset( $_POST['booster_import_settings'] );
|
||||
} else {
|
||||
$import_counter = 0;
|
||||
$import_settings = file_get_contents( $_FILES['booster_import_settings_file']['tmp_name'] );
|
||||
$import_settings = explode( PHP_EOL, preg_replace( '~(*BSR_ANYCRLF)\R~', PHP_EOL, $import_settings ) );
|
||||
if ( ! is_array( $import_settings ) || 2 !== count( $import_settings ) ) {
|
||||
$wcj_notice .= __( 'Wrong file format!', 'woocommerce-jetpack' );
|
||||
} else {
|
||||
$import_header = $import_settings[0];
|
||||
$required_header = 'Booster for WooCommerce';
|
||||
if ( $required_header !== substr( $import_header, 0, strlen( $required_header ) ) ) {
|
||||
$wcj_notice .= __( 'Wrong file format!', 'woocommerce-jetpack' );
|
||||
} else {
|
||||
$import_settings = json_decode( $import_settings[1], true );
|
||||
foreach ( $import_settings as $import_key => $import_setting ) {
|
||||
if ( strlen( $import_key ) > 4 && 'wcj_' === substr( $import_key, 0, 4 ) ) {
|
||||
update_option( $import_key, $import_setting );
|
||||
$import_counter++;
|
||||
}
|
||||
}
|
||||
$wcj_notice .= sprintf( __( '%d options successfully imported.', 'woocommerce-jetpack' ), $import_counter );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* manage_options_export.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function manage_options_export() {
|
||||
$export_settings = array();
|
||||
$export_counter = array();
|
||||
foreach ( WCJ()->modules as $module ) {
|
||||
$values = $module->get_settings();
|
||||
foreach ( $values as $value ) {
|
||||
if ( isset( $value['default'] ) && isset( $value['id'] ) ) {
|
||||
if ( isset ( $_POST['booster_export_settings'] ) ) {
|
||||
$export_settings[ $value['id'] ] = get_option( $value['id'], $value['default'] );
|
||||
if ( ! isset( $export_counter[ $module->short_desc ] ) ) {
|
||||
$export_counter[ $module->short_desc ] = 0;
|
||||
}
|
||||
$export_counter[ $module->short_desc ]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$export_settings = json_encode( $export_settings );
|
||||
$export_settings = 'Booster for WooCommerce v' . get_option( WCJ_VERSION_OPTION, 'NA' ) . PHP_EOL . $export_settings;
|
||||
header( "Content-Type: application/octet-stream" );
|
||||
header( "Content-Disposition: attachment; filename=booster_settings.txt" );
|
||||
header( "Content-Type: application/octet-stream" );
|
||||
header( "Content-Type: application/download" );
|
||||
header( "Content-Description: File Transfer" );
|
||||
header( "Content-Length: " . strlen( $export_settings ) );
|
||||
echo $export_settings;
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* manage_options_reset_meta.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
* @todo order items meta
|
||||
* @todo `... LIKE 'wcj_%'`
|
||||
*/
|
||||
function manage_options_reset_meta() {
|
||||
global $wpdb, $wcj_notice;
|
||||
$delete_counter_meta = 0;
|
||||
$plugin_meta = $wpdb->get_results( "SELECT * FROM $wpdb->postmeta WHERE meta_key LIKE '_wcj_%'" );
|
||||
foreach( $plugin_meta as $meta ) {
|
||||
delete_post_meta( $meta->post_id, $meta->meta_key );
|
||||
$delete_counter_meta++;
|
||||
}
|
||||
$wcj_notice .= sprintf( __( '%d meta successfully deleted.', 'woocommerce-jetpack' ), $delete_counter_meta );
|
||||
}
|
||||
|
||||
/**
|
||||
* manage_options_reset.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function manage_options_reset() {
|
||||
global $wpdb, $wcj_notice;
|
||||
$delete_counter_options = 0;
|
||||
$plugin_options = $wpdb->get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'wcj_%'" );
|
||||
foreach( $plugin_options as $option ) {
|
||||
delete_option( $option->option_name );
|
||||
delete_site_option( $option->option_name );
|
||||
$delete_counter_options++;
|
||||
}
|
||||
$wcj_notice .= sprintf( __( '%d options successfully deleted.', 'woocommerce-jetpack' ), $delete_counter_options );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Settings_Manager();
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce Tools
|
||||
*
|
||||
* @version 3.5.3
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Tools' ) ) :
|
||||
|
||||
class WCJ_Tools {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
function __construct() {
|
||||
if ( is_admin() ) {
|
||||
add_action( 'admin_menu', array( $this, 'add_wcj_tools' ), 100 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_wcj_tools.
|
||||
*
|
||||
* @version 3.5.3
|
||||
*/
|
||||
function add_wcj_tools() {
|
||||
add_submenu_page(
|
||||
'woocommerce',
|
||||
__( 'Booster for WooCommerce Tools', 'woocommerce-jetpack' ),
|
||||
__( 'Booster Tools', 'woocommerce-jetpack' ),
|
||||
( 'yes' === get_option( 'wcj_' . 'admin_tools' . '_enabled', 'no' ) && 'yes' === get_option( 'wcj_admin_tools_show_menus_to_admin_only', 'no' ) ? 'manage_options' : 'manage_woocommerce' ),
|
||||
'wcj-tools',
|
||||
array( $this, 'create_tools_page' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_tools_page.
|
||||
*
|
||||
* @version 2.3.10
|
||||
*/
|
||||
function create_tools_page() {
|
||||
|
||||
// Tabs
|
||||
$tabs = apply_filters( 'wcj_tools_tabs', array(
|
||||
array(
|
||||
'id' => 'dashboard',
|
||||
'title' => __( 'Tools Dashboard', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
$html = '<h2 class="nav-tab-wrapper woo-nav-tab-wrapper">';
|
||||
$active_tab = ( isset( $_GET['tab'] ) ) ? $_GET['tab'] : 'dashboard';
|
||||
foreach ( $tabs as $tab ) {
|
||||
$is_active = ( $active_tab === $tab['id'] ) ? 'nav-tab-active' : '';
|
||||
$html .= '<a href="' . add_query_arg( array( 'page' => 'wcj-tools', 'tab' => $tab['id'] ), get_admin_url() . 'admin.php' ) . '" class="nav-tab ' . $is_active . '">' . $tab['title'] . '</a>';
|
||||
}
|
||||
$html .= '</h2>';
|
||||
echo $html;
|
||||
|
||||
// Content
|
||||
if ( 'dashboard' === $active_tab ) {
|
||||
$title = __( 'Booster for WooCommerce Tools - Dashboard', 'woocommerce-jetpack' );
|
||||
$desc = __( 'This dashboard lets you check statuses and short descriptions of all available Booster for WooCommerce tools. Tools can be enabled through WooCommerce > Settings > Booster. Enabled tools will appear in the tabs menu above.', 'woocommerce-jetpack' );
|
||||
echo '<h3>' . $title . '</h3>';
|
||||
echo '<p>' . $desc . '</p>';
|
||||
echo '<table class="widefat" style="width:90%;">';
|
||||
echo '<tr>';
|
||||
echo '<th style="width:20%;">' . __( 'Tool', 'woocommerce-jetpack' ) . '</th>';
|
||||
echo '<th style="width:20%;">' . __( 'Module', 'woocommerce-jetpack' ) . '</th>';
|
||||
echo '<th style="width:50%;">' . __( 'Description', 'woocommerce-jetpack' ) . '</th>';
|
||||
echo '<th style="width:10%;">' . __( 'Status', 'woocommerce-jetpack' ) . '</th>';
|
||||
echo '</tr>';
|
||||
do_action( 'wcj_tools_' . 'dashboard' );
|
||||
echo '</table>';
|
||||
} else {
|
||||
do_action( 'wcj_tools_' . $active_tab );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Tools();
|
||||
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Modules Array
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
* @todo (maybe) split "Shipping & Orders", "Cart & Checkout", "Products", "Prices & Currencies" etc.
|
||||
*/
|
||||
|
||||
return apply_filters( 'wcj_modules', array(
|
||||
|
||||
'dashboard' => array(
|
||||
'label' => __( 'Dashboard', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'This dashboard lets you enable/disable any Booster\'s module. Each checkbox comes with short module\'s description. Please visit <a href="https://booster.io" target="_blank">https://booster.io</a> for detailed info on each feature.', 'woocommerce-jetpack' ),
|
||||
'all_cat_ids' => array(
|
||||
'alphabetically',
|
||||
'by_category',
|
||||
'active',
|
||||
'manager',
|
||||
),
|
||||
),
|
||||
|
||||
'prices_and_currencies' => array(
|
||||
'label' => __( 'Prices & Currencies', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Multicurrency, Price Converter, Wholesale Pricing, Name You Price, Price based on User Role and more.', 'woocommerce-jetpack' ),
|
||||
'all_cat_ids' => array(
|
||||
'price_by_country',
|
||||
'multicurrency',
|
||||
'multicurrency_base_price',
|
||||
'currency_per_product',
|
||||
'currency',
|
||||
'currency_external_products',
|
||||
'bulk_price_converter',
|
||||
'wholesale_price',
|
||||
'product_open_pricing',
|
||||
'offer_price',
|
||||
'price_by_user_role',
|
||||
'product_price_by_formula',
|
||||
'global_discount',
|
||||
'currency_exchange_rates',
|
||||
'price_formats',
|
||||
),
|
||||
),
|
||||
|
||||
'labels' => array(
|
||||
'label' => __( 'Button & Price Labels', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Add to Cart Labels, Call for Price, Custom Price Labels and more.', 'woocommerce-jetpack' ),
|
||||
'all_cat_ids' => array(
|
||||
'price_labels',
|
||||
'call_for_price',
|
||||
'free_price',
|
||||
'add_to_cart',
|
||||
'more_button_labels',
|
||||
),
|
||||
),
|
||||
|
||||
'products' => array(
|
||||
'label' => __( 'Products', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Bookings, Crowdfunding Products, Product Addons and Input Fields, Product Listings, Product Tabs and more.', 'woocommerce-jetpack' ),
|
||||
'all_cat_ids' => array(
|
||||
'product_listings',
|
||||
'tax_display',
|
||||
'admin_products_list',
|
||||
'products_per_page',
|
||||
'product_tabs',
|
||||
'product_custom_info',
|
||||
'related_products',
|
||||
'cross_sells',
|
||||
'upsells',
|
||||
'sorting',
|
||||
'sku',
|
||||
'stock',
|
||||
'product_input_fields',
|
||||
'product_add_to_cart',
|
||||
'add_to_cart_button_visibility',
|
||||
'purchase_data',
|
||||
'product_bookings',
|
||||
'crowdfunding',
|
||||
'product_addons',
|
||||
'product_images',
|
||||
'sale_flash',
|
||||
'product_by_country',
|
||||
'product_by_user_role',
|
||||
'product_custom_visibility',
|
||||
'product_by_time',
|
||||
'product_by_date',
|
||||
'product_by_user',
|
||||
'products_xml',
|
||||
'product_bulk_meta_editor',
|
||||
'product_msrp',
|
||||
),
|
||||
),
|
||||
|
||||
'cart_and_checkout' => array(
|
||||
'label' => __( 'Cart & Checkout', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Cart and Checkout Customization, Empty Cart Button, Mini Cart, Coupons and more.', 'woocommerce-jetpack' ),
|
||||
'all_cat_ids' => array(
|
||||
'cart',
|
||||
'cart_customization',
|
||||
'empty_cart',
|
||||
'mini_cart',
|
||||
'url_coupons',
|
||||
'coupon_code_generator',
|
||||
'coupon_by_user_role',
|
||||
'checkout_core_fields',
|
||||
'checkout_custom_fields',
|
||||
'checkout_files_upload',
|
||||
'checkout_custom_info',
|
||||
'checkout_customization',
|
||||
'checkout_fees',
|
||||
'eu_vat_number',
|
||||
),
|
||||
),
|
||||
|
||||
'payment_gateways' => array(
|
||||
'label' => __( 'Payment Gateways', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Custom Payment Gateways, Gateways Currency, Gateways Fees and Discounts and more.', 'woocommerce-jetpack' ),
|
||||
'all_cat_ids' => array(
|
||||
'payment_gateways',
|
||||
'payment_gateways_icons',
|
||||
'payment_gateways_fees',
|
||||
'payment_gateways_per_category',
|
||||
'payment_gateways_currency',
|
||||
'payment_gateways_by_currency',
|
||||
'payment_gateways_min_max',
|
||||
'payment_gateways_by_country',
|
||||
'payment_gateways_by_user_role',
|
||||
'payment_gateways_by_shipping',
|
||||
),
|
||||
),
|
||||
|
||||
'shipping_and_orders' => array(
|
||||
'label' => __( 'Shipping & Orders', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Order Custom Statuses, Order Minimum Amount, Order Numbers, Custom Shipping Methods and more.', 'woocommerce-jetpack' ),
|
||||
'all_cat_ids' => array(
|
||||
'shipping',
|
||||
'shipping_options',
|
||||
'shipping_icons',
|
||||
'shipping_description',
|
||||
'shipping_time',
|
||||
'left_to_free_shipping',
|
||||
'shipping_calculator',
|
||||
'shipping_by_user_role',
|
||||
'shipping_by_products',
|
||||
'shipping_by_cities',
|
||||
'shipping_by_order_amount',
|
||||
'address_formats',
|
||||
'orders',
|
||||
'admin_orders_list',
|
||||
'order_min_amount',
|
||||
'order_numbers',
|
||||
'order_custom_statuses',
|
||||
'order_quantities',
|
||||
'max_products_per_user',
|
||||
),
|
||||
),
|
||||
|
||||
'pdf_invoicing' => array(
|
||||
'label' => __( 'PDF Invoicing & Packing Slips', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'PDF Documents', 'woocommerce-jetpack' ),
|
||||
'all_cat_ids' => array(
|
||||
'pdf_invoicing',
|
||||
'pdf_invoicing_numbering',
|
||||
'pdf_invoicing_templates',
|
||||
'pdf_invoicing_header',
|
||||
'pdf_invoicing_footer',
|
||||
'pdf_invoicing_styling',
|
||||
'pdf_invoicing_page',
|
||||
'pdf_invoicing_emails',
|
||||
'pdf_invoicing_display',
|
||||
'pdf_invoicing_advanced',
|
||||
),
|
||||
),
|
||||
|
||||
'emails_and_misc' => array(
|
||||
'label' => __( 'Emails & Misc.', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Emails, Reports, Export, Admin Tools, General Options and more.', 'woocommerce-jetpack' ),
|
||||
'all_cat_ids' => array(
|
||||
'general',
|
||||
'breadcrumbs',
|
||||
'admin_bar',
|
||||
'export',
|
||||
'my_account',
|
||||
'old_slugs',
|
||||
'reports',
|
||||
'admin_tools',
|
||||
'emails',
|
||||
'email_options',
|
||||
'emails_verification',
|
||||
'wpml',
|
||||
'custom_css',
|
||||
'custom_js',
|
||||
'track_users',
|
||||
'modules_by_user_roles',
|
||||
'product_info', // deprecated
|
||||
),
|
||||
),
|
||||
|
||||
) );
|
||||
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Add to Cart Button Visibility
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.3.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Add_To_Cart_Button_Visibility' ) ) :
|
||||
|
||||
class WCJ_Add_To_Cart_Button_Visibility extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'add_to_cart_button_visibility';
|
||||
$this->short_desc = __( 'Add to Cart Button Visibility', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Enable/disable Add to Cart button globally or on per product basis.', 'woocommerce-jetpack' );
|
||||
$this->extra_desc = '<em>' . sprintf(
|
||||
__( 'If you need to enable/disable Add to Cart button for some <strong>user roles</strong> only, we suggest using this module in conjunction with Booster\'s %s module.', 'woocommerce-jetpack' ),
|
||||
'<a href="' . wcj_get_module_settings_admin_url( 'modules_by_user_roles' ) . '">' .
|
||||
__( 'Modules By User Roles', 'woocommerce-jetpack' ) . '</a>'
|
||||
) . '</em>';
|
||||
$this->link_slug = 'woocommerce-add-to-cart-button-visibility';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// All products
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_button_global_enabled', 'no' ) ) {
|
||||
// Archives
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_button_disable_archives', 'no' ) ) {
|
||||
add_action( 'init', array( $this, 'add_to_cart_button_disable_archives' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_after_shop_loop_item', array( $this, 'add_to_cart_button_archives_content' ), 10 );
|
||||
}
|
||||
// Single Product
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_button_disable_single', 'no' ) ) {
|
||||
add_action( 'init', array( $this, 'add_to_cart_button_disable_single' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_single_product_summary', array( $this, 'add_to_cart_button_single_content' ), 30 );
|
||||
}
|
||||
}
|
||||
// Per category
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_button_per_category_enabled', 'no' ) ) {
|
||||
// Single Product
|
||||
add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'add_to_cart_button_disable_start_per_category' ), PHP_INT_MAX, 0 );
|
||||
add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'add_to_cart_button_disable_end_per_category' ), PHP_INT_MAX, 0 );
|
||||
// Archives
|
||||
add_filter( 'woocommerce_loop_add_to_cart_link', array( $this, 'add_to_cart_button_loop_disable_per_category' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
// Per product
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_button_per_product_enabled', 'no' ) ) {
|
||||
// Single Product
|
||||
add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'add_to_cart_button_disable_start' ), PHP_INT_MAX, 0 );
|
||||
add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'add_to_cart_button_disable_end' ), PHP_INT_MAX, 0 );
|
||||
// Archives
|
||||
add_filter( 'woocommerce_loop_add_to_cart_link', array( $this, 'add_to_cart_button_loop_disable' ), PHP_INT_MAX, 2 );
|
||||
// Metaboxes
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_button_archives_content.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
*/
|
||||
function add_to_cart_button_archives_content() {
|
||||
if ( '' != ( $content = get_option( 'wcj_add_to_cart_button_archives_content', '' ) ) ) {
|
||||
echo do_shortcode( $content );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_button_single_content.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
*/
|
||||
function add_to_cart_button_single_content() {
|
||||
if ( '' != ( $content = get_option( 'wcj_add_to_cart_button_single_content', '' ) ) ) {
|
||||
echo do_shortcode( $content );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_button_disable_end_per_category.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function add_to_cart_button_disable_end_per_category() {
|
||||
$cats_to_hide = get_option( 'wcj_add_to_cart_button_per_category_disable_single', '' );
|
||||
if ( ! empty( $cats_to_hide ) && 0 != get_the_ID() && wcj_is_product_term( get_the_ID(), $cats_to_hide, 'product_cat' ) ) {
|
||||
ob_end_clean();
|
||||
echo do_shortcode( get_option( 'wcj_add_to_cart_button_per_category_content_single', '' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_button_disable_start_per_category.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function add_to_cart_button_disable_start_per_category() {
|
||||
$cats_to_hide = get_option( 'wcj_add_to_cart_button_per_category_disable_single', '' );
|
||||
if ( ! empty( $cats_to_hide ) && 0 != get_the_ID() && wcj_is_product_term( get_the_ID(), $cats_to_hide, 'product_cat' ) ) {
|
||||
ob_start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_button_loop_disable_per_category.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function add_to_cart_button_loop_disable_per_category( $link, $_product ) {
|
||||
$cats_to_hide = get_option( 'wcj_add_to_cart_button_per_category_disable_loop', '' );
|
||||
if ( ! empty( $cats_to_hide ) && wcj_is_product_term( wcj_get_product_id_or_variation_parent_id( $_product ), $cats_to_hide, 'product_cat' ) ) {
|
||||
return do_shortcode( get_option( 'wcj_add_to_cart_button_per_category_content_loop', '' ) );
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_button_disable_single.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function add_to_cart_button_disable_single() {
|
||||
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_button_disable_archives.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function add_to_cart_button_disable_archives() {
|
||||
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_button_loop_disable.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_to_cart_button_loop_disable( $link, $_product ) {
|
||||
if ( 0 != get_the_ID() && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_loop_disable', true ) ) {
|
||||
return do_shortcode( get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_loop_disable_content', true ) );
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_button_disable_end.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_to_cart_button_disable_end() {
|
||||
if ( 0 != get_the_ID() && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_disable', true ) ) {
|
||||
ob_end_clean();
|
||||
echo do_shortcode( get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_disable_content', true ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_button_disable_start.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_to_cart_button_disable_start() {
|
||||
if ( 0 != get_the_ID() && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_disable', true ) ) {
|
||||
ob_start();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Add_To_Cart_Button_Visibility();
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Add to Cart
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Add_To_Cart' ) ) :
|
||||
|
||||
class WCJ_Add_To_Cart extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.3.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'add_to_cart';
|
||||
$this->short_desc = __( 'Add to Cart Button Labels', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Change text for Add to Cart button by product type, by product category or for individual products.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-add-to-cart-labels';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
include_once( 'add-to-cart/class-wcj-add-to-cart-per-category.php' );
|
||||
include_once( 'add-to-cart/class-wcj-add-to-cart-per-product.php' );
|
||||
include_once( 'add-to-cart/class-wcj-add-to-cart-per-product-type.php' );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Add_To_Cart();
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Address Formats
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Address_Formats' ) ) :
|
||||
|
||||
class WCJ_Address_Formats extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'address_formats';
|
||||
$this->short_desc = __( 'Address Formats', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set address format in orders on per country basis. Force base country display.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-address-formats';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_localisation_address_formats', array( $this, 'customize_address_formats' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_formatted_address_force_country_display', array( $this, 'customize_force_country_display' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* customize_force_country_display.
|
||||
*
|
||||
* @version 2.7.0
|
||||
*/
|
||||
function customize_force_country_display( $display ) {
|
||||
return ( 'yes' === get_option( 'wcj_address_formats_force_country_display', 'no' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* customize_address_formats.
|
||||
*/
|
||||
function customize_address_formats( $formats ) {
|
||||
$modified_formats = array();
|
||||
$default_formats = $this->get_default_address_formats();
|
||||
foreach ( $default_formats as $country_code => $format ) {
|
||||
$default_format = isset( $formats[ $country_code ] ) ? $formats[ $country_code ] : $format;
|
||||
$format = get_option( 'wcj_address_formats_country_' . $country_code, $default_format );
|
||||
$modified_formats[ $country_code ] = $format;
|
||||
}
|
||||
return $modified_formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get country address formats
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_default_address_formats() {
|
||||
// Common formats
|
||||
$postcode_before_city = "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}";
|
||||
$default = "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode}\n{country}";
|
||||
// Define address formats
|
||||
$formats = array(
|
||||
'default' => $default,
|
||||
'AU' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}",
|
||||
'AT' => $postcode_before_city,
|
||||
'BE' => $postcode_before_city,
|
||||
'CA' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}",
|
||||
'CH' => $postcode_before_city,
|
||||
'CL' => "{company}\n{name}\n{address_1}\n{address_2}\n{state}\n{postcode} {city}\n{country}",
|
||||
'CN' => "{country} {postcode}\n{state}, {city}, {address_2}, {address_1}\n{company}\n{name}",
|
||||
'CZ' => $postcode_before_city,
|
||||
'DE' => $postcode_before_city,
|
||||
'EE' => $postcode_before_city,
|
||||
'FI' => $postcode_before_city,
|
||||
'DK' => $postcode_before_city,
|
||||
'FR' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city_upper}\n{country}",
|
||||
'HK' => "{company}\n{first_name} {last_name_upper}\n{address_1}\n{address_2}\n{city_upper}\n{state_upper}\n{country}",
|
||||
'HU' => "{name}\n{company}\n{city}\n{address_1}\n{address_2}\n{postcode}\n{country}",
|
||||
'IN' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} - {postcode}\n{state}, {country}",
|
||||
'IS' => $postcode_before_city,
|
||||
'IT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode}\n{city}\n{state_upper}\n{country}",
|
||||
'JP' => "{postcode}\n{state}{city}{address_1}\n{address_2}\n{company}\n{last_name} {first_name}\n{country}",
|
||||
'TW' => "{company}\n{last_name} {first_name}\n{address_1}\n{address_2}\n{state}, {city} {postcode}\n{country}",
|
||||
'LI' => $postcode_before_city,
|
||||
'NL' => $postcode_before_city,
|
||||
'NZ' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {postcode}\n{country}",
|
||||
'NO' => $postcode_before_city,
|
||||
'PL' => $postcode_before_city,
|
||||
'SK' => $postcode_before_city,
|
||||
'SI' => $postcode_before_city,
|
||||
'ES' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{state}\n{country}",
|
||||
'SE' => $postcode_before_city,
|
||||
'TR' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city} {state}\n{country}",
|
||||
'US' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}, {state_code} {postcode}\n{country}",
|
||||
'VN' => "{name}\n{company}\n{address_1}\n{city}\n{country}",
|
||||
);
|
||||
$all_countries = wcj_get_countries();
|
||||
foreach ( $all_countries as $country_code => $country_name ) {
|
||||
if ( ! isset( $formats[ $country_code ] ) ) {
|
||||
$formats[ $country_code ] = $default;
|
||||
}
|
||||
}
|
||||
ksort( $formats );
|
||||
return $formats;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Address_Formats();
|
||||
@@ -0,0 +1,620 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Admin Bar
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.9.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Admin_Bar' ) ) :
|
||||
|
||||
class WCJ_Admin_Bar extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) custom user nodes
|
||||
* @todo (maybe) optional nodes selection
|
||||
* @todo (maybe) add WooCommerce versions (from / to) to nodes
|
||||
* @todo (maybe) customizable icons
|
||||
* @todo (maybe) separate admin bar menu: "Booster Modules", "Booster Tools", "WooCommerce Reports", "WooCommerce Products", "WooCommerce Settings"
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'admin_bar';
|
||||
$this->short_desc = __( 'Admin Bar', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'WooCommerce admin bar.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-admin-bar';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( 'yes' === get_option( 'wcj_admin_bar_wc_enabled', 'yes' ) ) {
|
||||
add_action( 'admin_bar_menu', array( $this, 'add_woocommerce_admin_bar' ), PHP_INT_MAX );
|
||||
add_action( 'wp_head', array( $this, 'add_woocommerce_admin_bar_icon_style' ) );
|
||||
add_action( 'admin_head', array( $this, 'add_woocommerce_admin_bar_icon_style' ) );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_admin_bar_booster_enabled', 'yes' ) ) {
|
||||
add_action( 'admin_bar_menu', array( $this, 'add_booster_admin_bar' ), PHP_INT_MAX );
|
||||
if ( 'yes' === get_option( 'wcj_admin_bar_booster_active_enabled', 'yes' ) ) {
|
||||
add_action( 'admin_bar_menu', array( $this, 'add_booster_active_admin_bar' ), PHP_INT_MAX );
|
||||
}
|
||||
add_action( 'wp_head', array( $this, 'add_booster_admin_bar_icon_style' ) );
|
||||
add_action( 'admin_head', array( $this, 'add_booster_admin_bar_icon_style' ) );
|
||||
}
|
||||
add_action( 'woojetpack_after_settings_save', array( $this, 'reload_page_after_settings_save' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reload_page_after_settings_save.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) somehow add "Your settings have been saved." admin notice
|
||||
*/
|
||||
function reload_page_after_settings_save( $sections, $current_section ) {
|
||||
// This function is needed so admin bar menus would appear immediately after module settings are saved (i.e. without additional page refresh)
|
||||
if ( $this->id === $current_section ) {
|
||||
wp_safe_redirect( add_query_arg( '', '' ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_booster_admin_bar_icon_style.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function add_booster_admin_bar_icon_style() {
|
||||
echo '<style type="text/css"> #wpadminbar #wp-admin-bar-booster .ab-icon:before { content: "\f185"; top: 3px; } </style>';
|
||||
echo '<style type="text/css"> #wpadminbar #wp-admin-bar-booster-active .ab-icon:before { content: "\f155"; top: 3px; } </style>';
|
||||
}
|
||||
|
||||
/**
|
||||
* add_woocommerce_admin_bar_icon_style.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function add_woocommerce_admin_bar_icon_style() {
|
||||
echo '<style type="text/css"> #wpadminbar #wp-admin-bar-wcj-wc .ab-icon:before { content: "\f174"; top: 3px; } </style>';
|
||||
}
|
||||
|
||||
/**
|
||||
* add_woocommerce_admin_bar_nodes.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, $parent_id ) {
|
||||
foreach ( $nodes as $node_id => $node ) {
|
||||
$id = ( false !== $parent_id ? $parent_id . '-' . $node_id : $node_id );
|
||||
$args = array(
|
||||
'parent' => $parent_id,
|
||||
'id' => $id,
|
||||
'title' => $node['title'],
|
||||
'href' => $node['href'],
|
||||
'meta' => array( 'title' => $node['title'] ),
|
||||
);
|
||||
if ( isset( $node['meta'] ) ) {
|
||||
$args['meta'] = array_merge( $args['meta'], $node['meta'] );
|
||||
}
|
||||
$wp_admin_bar->add_node( $args );
|
||||
if ( isset( $node['nodes'] ) ) {
|
||||
// Recursion
|
||||
$this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $node['nodes'], $id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_nodes_booster_modules.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) dashes instead of underscores
|
||||
* @todo (maybe) dashboard > alphabetically - list all modules
|
||||
* @todo (maybe) dashboard > by_category - list all modules
|
||||
*/
|
||||
function get_nodes_booster_modules() {
|
||||
$nodes = array();
|
||||
$cats = include( wcj_plugin_path() . '/includes/admin/' . 'wcj-modules-cats.php' );
|
||||
$this->active_modules = array();
|
||||
foreach ( $cats as $id => $label_info ) {
|
||||
$nodes[ $id ] = array(
|
||||
'title' => $label_info['label'],
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $id ),
|
||||
'meta' => array( 'title' => strip_tags( $label_info['desc'] ) ),
|
||||
);
|
||||
if ( 'dashboard' === $id ) {
|
||||
$nodes[ $id ]['nodes'] = apply_filters( 'wcj_admin_bar_dashboard_nodes', array(
|
||||
'alphabetically' => array(
|
||||
'title' => __( 'Alphabetically', 'woocommerce-jetpack' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard§ion=alphabetically' ),
|
||||
),
|
||||
'by_category' => array(
|
||||
'title' => __( 'By Category', 'woocommerce-jetpack' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard§ion=by_category' ),
|
||||
),
|
||||
'active' => array(
|
||||
'title' => __( 'Active', 'woocommerce-jetpack' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard§ion=active' ),
|
||||
),
|
||||
'manager' => array(
|
||||
'title' => __( 'Manage Settings', 'woocommerce-jetpack' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard§ion=manager' ),
|
||||
),
|
||||
) );
|
||||
} else {
|
||||
$cat_nodes = array();
|
||||
foreach ( $label_info['all_cat_ids'] as $link_id ) {
|
||||
if ( wcj_is_module_deprecated( $link_id, false, true ) ) {
|
||||
continue;
|
||||
}
|
||||
$cat_nodes[ $link_id ] = array(
|
||||
'title' => WCJ()->modules[ $link_id ]->short_desc,
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $id . '§ion=' . $link_id ),
|
||||
'meta' => array( 'title' => WCJ()->modules[ $link_id ]->desc ),
|
||||
'nodes' => array(
|
||||
'settings' => array(
|
||||
'title' => __( 'Settings', 'woocommerce-jetpack' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=' . $id . '§ion=' . $link_id ),
|
||||
),
|
||||
'docs' => array(
|
||||
'title' => __( 'Documentation', 'woocommerce-jetpack' ),
|
||||
'href' => WCJ()->modules[ $link_id ]->link . '?utm_source=module_documentation&utm_medium=admin_bar_link&utm_campaign=booster_documentation',
|
||||
'meta' => array( 'target' => '_blank' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
if ( WCJ()->modules[ $link_id ]->is_enabled() && 'module' === WCJ()->modules[ $link_id ]->type ) {
|
||||
$this->active_modules[ $link_id ] = $cat_nodes[ $link_id ];
|
||||
}
|
||||
}
|
||||
usort( $cat_nodes, array( $this, 'usort_compare_by_title' ) );
|
||||
$nodes[ $id ]['nodes'] = $cat_nodes;
|
||||
}
|
||||
}
|
||||
if ( ! empty( $this->active_modules ) ) {
|
||||
usort( $this->active_modules, array( $this, 'usort_compare_by_title' ) );
|
||||
$nodes['dashboard']['nodes']['active']['nodes'] = $this->active_modules;
|
||||
}
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* usort_compare_by_title.
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function usort_compare_by_title( $a, $b ) {
|
||||
return strcasecmp( $a['title'], $b['title'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* get_nodes_booster_tools.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function get_nodes_booster_tools() {
|
||||
$nodes = array();
|
||||
$tools = apply_filters( 'wcj_tools_tabs', array(
|
||||
array(
|
||||
'id' => 'dashboard',
|
||||
'title' => __( 'Dashboard', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'This dashboard lets you check statuses and short descriptions of all available Booster for WooCommerce tools. Tools can be enabled through WooCommerce > Settings > Booster.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
foreach ( $tools as $tool ) {
|
||||
$nodes[ $tool['id'] ] = array(
|
||||
'title' => $tool['title'],
|
||||
'href' => admin_url( 'admin.php?page=wcj-tools&tab=' . $tool['id'] ),
|
||||
);
|
||||
if ( isset( $tool['desc'] ) ) {
|
||||
$nodes[ $tool['id'] ]['meta']['title'] = $tool['desc'];
|
||||
}
|
||||
}
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_booster_active_admin_bar.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function add_booster_active_admin_bar( $wp_admin_bar ) {
|
||||
if ( ! current_user_can( 'manage_woocommerce' ) ) {
|
||||
return;
|
||||
}
|
||||
$tools = array(
|
||||
'tools' => array(
|
||||
'title' => __( 'Tools', 'woocommerce-jetpack' ),
|
||||
'href' => admin_url( 'admin.php?page=wcj-tools' ),
|
||||
'nodes' => $this->get_nodes_booster_tools(),
|
||||
),
|
||||
);
|
||||
unset( $tools['tools']['nodes']['dashboard'] );
|
||||
$nodes = array(
|
||||
'booster-active' => array(
|
||||
'title' => '<span class="ab-icon"></span>' . __( 'Booster: Active', 'woocommerce-jetpack' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=dashboard§ion=active' ),
|
||||
'meta' => array(
|
||||
'title' => __( 'Booster - Active', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'nodes' => array_merge( $this->active_modules, $tools ),
|
||||
),
|
||||
);
|
||||
$this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_booster_admin_bar.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function add_booster_admin_bar( $wp_admin_bar ) {
|
||||
if ( ! current_user_can( 'manage_woocommerce' ) ) {
|
||||
return;
|
||||
}
|
||||
$nodes = array(
|
||||
'booster' => array(
|
||||
'title' => '<span class="ab-icon"></span>' . __( 'Booster', 'woocommerce-jetpack' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack' ),
|
||||
'meta' => array(
|
||||
'title' => __( 'Booster - Settings', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'nodes' => array(
|
||||
'modules' => array(
|
||||
'title' => __( 'Modules', 'woocommerce-jetpack' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=jetpack' ),
|
||||
'nodes' => $this->get_nodes_booster_modules(),
|
||||
),
|
||||
'tools' => array(
|
||||
'title' => __( 'Tools', 'woocommerce-jetpack' ),
|
||||
'href' => admin_url( 'admin.php?page=wcj-tools' ),
|
||||
'nodes' => $this->get_nodes_booster_tools(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* get_nodes_orders_reports.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function get_nodes_orders_reports() {
|
||||
$nodes = array();
|
||||
$reports = array(
|
||||
'sales_by_date' => __( 'Sales by date', 'woocommerce' ),
|
||||
'sales_by_product' => __( 'Sales by product', 'woocommerce' ),
|
||||
'sales_by_category' => __( 'Sales by category', 'woocommerce' ),
|
||||
'coupon_usage' => __( 'Coupons by date', 'woocommerce' ),
|
||||
);
|
||||
foreach ( $reports as $report_id => $report_title ) {
|
||||
$nodes[ $report_id ] = array(
|
||||
'title' => $report_title,
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id ),
|
||||
'nodes' => array(
|
||||
'7day' => array(
|
||||
'title' => __( 'Last 7 days', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=7day' ),
|
||||
),
|
||||
'month' => array(
|
||||
'title' => __( 'This month', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=month' ),
|
||||
),
|
||||
'last-month' => array(
|
||||
'title' => __( 'Last month', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=last_month' ),
|
||||
),
|
||||
'year' => array(
|
||||
'title' => __( 'Year', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=orders&report=' . $report_id . '&range=year' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_woocommerce_admin_bar.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) reports > customers > customers > add dates
|
||||
* @todo (maybe) reports > taxes > taxes_by_code > add dates
|
||||
* @todo (maybe) reports > taxes > taxes_by_date > add dates
|
||||
* @todo (maybe) settings > add custom sections (i.e. Booster and other plugins)
|
||||
* @todo (maybe) extensions > add sections
|
||||
*/
|
||||
function add_woocommerce_admin_bar( $wp_admin_bar ) {
|
||||
if ( ! current_user_can( 'manage_woocommerce' ) ) {
|
||||
return;
|
||||
}
|
||||
$nodes = array(
|
||||
'wcj-wc' => array(
|
||||
'title' => '<span class="ab-icon"></span>' . __( 'WooCommerce', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings' ),
|
||||
'meta' => array(
|
||||
'title' => __( 'WooCommerce settings', 'woocommerce' ),
|
||||
),
|
||||
'nodes' => array(
|
||||
'orders' => array(
|
||||
'title' => __( 'Orders', 'woocommerce' ),
|
||||
'href' => admin_url( 'edit.php?post_type=shop_order' ),
|
||||
'nodes' => array(
|
||||
'orders' => array(
|
||||
'title' => __( 'Orders', 'woocommerce' ),
|
||||
'href' => admin_url( 'edit.php?post_type=shop_order' ),
|
||||
),
|
||||
'add-order' => array(
|
||||
'title' => __( 'Add order', 'woocommerce' ),
|
||||
'href' => admin_url( 'post-new.php?post_type=shop_order' ),
|
||||
),
|
||||
'customers' => array(
|
||||
'title' => __( 'Customers', 'woocommerce' ),
|
||||
'href' => admin_url( 'users.php?role=customer' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'reports' => array(
|
||||
'title' => __( 'Reports', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports' ),
|
||||
'nodes' => array(
|
||||
'orders' => array(
|
||||
'title' => __( 'Orders', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=orders' ),
|
||||
'nodes' => $this->get_nodes_orders_reports(),
|
||||
),
|
||||
'customers' => array(
|
||||
'title' => __( 'Customers', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=customers' ),
|
||||
'nodes' => array(
|
||||
'customers' => array(
|
||||
'title' => __( 'Customers vs. guests', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=customers&report=customers' ),
|
||||
),
|
||||
'customer-list' => array(
|
||||
'title' => __( 'Customer list', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=customers&report=customer_list' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'stock' => array(
|
||||
'title' => __( 'Stock', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=stock' ),
|
||||
'nodes' => array(
|
||||
'low-in-stock' => array(
|
||||
'title' => __( 'Low in stock', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=stock&report=low_in_stock' ),
|
||||
),
|
||||
'out-of-stock' => array(
|
||||
'title' => __( 'Out of stock', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=stock&report=out_of_stock' ),
|
||||
),
|
||||
'most-stocked' => array(
|
||||
'title' => __( 'Most Stocked', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=stock&report=most_stocked' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'taxes' => array(
|
||||
'title' => __( 'Taxes', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=taxes' ),
|
||||
'nodes' => array(
|
||||
'taxes-by-code' => array(
|
||||
'title' => __( 'Taxes by code', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=taxes&report=taxes_by_code' ),
|
||||
),
|
||||
'taxes-by-date' => array(
|
||||
'title' => __( 'Taxes by date', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-reports&tab=taxes&report=taxes_by_date' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
'products' => array(
|
||||
'title' => __( 'Products', 'woocommerce' ),
|
||||
'href' => admin_url( 'edit.php?post_type=product' ),
|
||||
'nodes' => array(
|
||||
'products' => array(
|
||||
'title' => __( 'Products', 'woocommerce' ),
|
||||
'href' => admin_url( 'edit.php?post_type=product' ),
|
||||
),
|
||||
'add-product' => array(
|
||||
'title' => __( 'Add product', 'woocommerce' ),
|
||||
'href' => admin_url( 'post-new.php?post_type=product' ),
|
||||
),
|
||||
'categories' => array(
|
||||
'title' => __( 'Categories', 'woocommerce' ),
|
||||
'href' => admin_url( 'edit-tags.php?taxonomy=product_cat&post_type=product' ),
|
||||
),
|
||||
'tags' => array(
|
||||
'title' => __( 'Tags', 'woocommerce' ),
|
||||
'href' => admin_url( 'edit-tags.php?taxonomy=product_tag&post_type=product' ),
|
||||
),
|
||||
'attributes' => array(
|
||||
'title' => __( 'Attributes', 'woocommerce' ),
|
||||
'href' => admin_url( 'edit.php?post_type=product&page=product_attributes' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'coupons' => array(
|
||||
'title' => __( 'Coupons', 'woocommerce' ),
|
||||
'href' => admin_url( 'edit.php?post_type=shop_coupon' ),
|
||||
'nodes' => array(
|
||||
'coupons' => array(
|
||||
'title' => __( 'Coupons', 'woocommerce' ),
|
||||
'href' => admin_url( 'edit.php?post_type=shop_coupon' ),
|
||||
),
|
||||
'add-coupon' => array(
|
||||
'title' => __( 'Add coupon', 'woocommerce' ),
|
||||
'href' => admin_url( 'post-new.php?post_type=shop_coupon' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'settings' => array(
|
||||
'title' => __( 'Settings', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings' ),
|
||||
'nodes' => array(
|
||||
'general' => array(
|
||||
'title' => __( 'General', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=general' ),
|
||||
),
|
||||
'products' => array(
|
||||
'title' => __( 'Products', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=products' ),
|
||||
'nodes' => array(
|
||||
'general' => array(
|
||||
'title' => __( 'General', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=products§ion' ),
|
||||
),
|
||||
'display' => array(
|
||||
'title' => __( 'Display', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=products§ion=display' ),
|
||||
),
|
||||
'inventory' => array(
|
||||
'title' => __( 'Inventory', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=products§ion=inventory' ),
|
||||
),
|
||||
'downloadable' => array(
|
||||
'title' => __( 'Downloadable products', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=products§ion=downloadable' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'tax' => array(
|
||||
'title' => __( 'Tax', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=tax' ),
|
||||
'nodes' => array(
|
||||
'tax-options' => array(
|
||||
'title' => __( 'Tax options', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=tax§ion' ),
|
||||
),
|
||||
'standard-rates' => array(
|
||||
'title' => __( 'Standard rates', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=tax§ion=standard' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'shipping' => array(
|
||||
'title' => __( 'Shipping', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping' ),
|
||||
'nodes' => array(
|
||||
'shipping-zones' => array(
|
||||
'title' => __( 'Shipping zones', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping§ion' ),
|
||||
),
|
||||
'shipping-options' => array(
|
||||
'title' => __( 'Shipping options', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=options' ),
|
||||
),
|
||||
'shipping-classes' => array(
|
||||
'title' => __( 'Shipping classes', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=classes' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'checkout' => array(
|
||||
'title' => __( 'Checkout', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout' ),
|
||||
'nodes' => array(
|
||||
'checkout-options' => array(
|
||||
'title' => __( 'Checkout options', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout§ion' ),
|
||||
),
|
||||
'bacs' => array(
|
||||
'title' => __( 'BACS', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=bacs' ),
|
||||
),
|
||||
'cheque' => array(
|
||||
'title' => __( 'Check payments', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=cheque' ),
|
||||
),
|
||||
'cod' => array(
|
||||
'title' => __( 'Cash on delivery', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=cod' ),
|
||||
),
|
||||
'paypal' => array(
|
||||
'title' => __( 'PayPal', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=paypal' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'account' => array(
|
||||
'title' => __( 'Account', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=account' ),
|
||||
),
|
||||
'email' => array(
|
||||
'title' => __( 'Emails', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=email' ),
|
||||
),
|
||||
'api' => array(
|
||||
'title' => __( 'API', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=api' ),
|
||||
'nodes' => array(
|
||||
'settings' => array(
|
||||
'title' => __( 'Settings', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=api§ion' ),
|
||||
),
|
||||
'keys' => array(
|
||||
'title' => __( 'Keys/Apps', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=api§ion=keys' ),
|
||||
),
|
||||
'webhooks' => array(
|
||||
'title' => __( 'Webhooks', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-settings&tab=api§ion=webhooks' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
'system-status' => array(
|
||||
'title' => __( 'System status', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-status' ),
|
||||
'nodes' => array(
|
||||
'system-status' => array(
|
||||
'title' => __( 'System status', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-status&tab=status' ),
|
||||
),
|
||||
'tools' => array(
|
||||
'title' => __( 'Tools', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-status&tab=tools' ),
|
||||
),
|
||||
'logs' => array(
|
||||
'title' => __( 'Logs', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-status&tab=logs' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'extensions' => array(
|
||||
'title' => __( 'Extensions', 'woocommerce' ),
|
||||
'href' => admin_url( 'admin.php?page=wc-addons' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->add_woocommerce_admin_bar_nodes( $wp_admin_bar, $nodes, false );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Admin_Bar();
|
||||
@@ -0,0 +1,419 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Admin Orders List
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.2.4
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Admin_Orders_List' ) ) :
|
||||
|
||||
class WCJ_Admin_Orders_List extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'admin_orders_list';
|
||||
$this->short_desc = __( 'Admin Orders List', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Customize admin orders list: add custom columns; add multiple status filtering.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-admin-orders-list';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
// Custom columns
|
||||
if ( 'yes' === get_option( 'wcj_order_admin_list_custom_columns_enabled', 'no' ) ) {
|
||||
add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_order_columns' ), PHP_INT_MAX - 1 );
|
||||
add_action( 'manage_shop_order_posts_custom_column', array( $this, 'render_order_column' ), PHP_INT_MAX );
|
||||
if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) || 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
|
||||
// Billing country or Currency filtering
|
||||
add_action( 'restrict_manage_posts', array( $this, 'restrict_manage_posts' ) );
|
||||
add_filter( 'parse_query', array( $this, 'parse_query' ) );
|
||||
}
|
||||
// Maybe make sortable custom columns
|
||||
add_filter( 'manage_edit-shop_order_sortable_columns', array( $this, 'shop_order_sortable_columns' ) );
|
||||
add_action( 'pre_get_posts', array( $this, 'shop_order_pre_get_posts_order_by_column' ) );
|
||||
}
|
||||
|
||||
// Multiple status
|
||||
if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_enabled', 'no' ) ) {
|
||||
if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_not_completed_link', 'no' ) ) {
|
||||
add_filter( 'views_edit-shop_order', array( $this, 'add_shop_order_multiple_statuses_not_completed_link' ) );
|
||||
add_action( 'pre_get_posts', array( $this, 'filter_shop_order_multiple_statuses_not_completed_link' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
if ( 'no' != get_option( 'wcj_order_admin_list_multiple_status_filter', 'no' ) ) {
|
||||
add_action( 'restrict_manage_posts', array( $this, 'add_shop_order_multiple_statuses' ), PHP_INT_MAX, 2 );
|
||||
add_action( 'pre_get_posts', array( $this, 'filter_shop_order_multiple_statuses' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_order_admin_list_hide_default_statuses_menu', 'no' ) ) {
|
||||
add_action( 'admin_head', array( $this, 'hide_default_statuses_menu' ), PHP_INT_MAX );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_admin_menu', 'no' ) ) {
|
||||
add_action( 'admin_menu', array( $this, 'admin_menu_multiple_status' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Columns Order
|
||||
if ( 'yes' === get_option( 'wcj_order_admin_list_columns_order_enabled', 'no' ) ) {
|
||||
add_filter( 'manage_edit-shop_order_columns', array( $this, 'rearange_order_columns' ), PHP_INT_MAX - 1 );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* admin_menu_multiple_status.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.7.0
|
||||
* @todo add presets as links (same as "Not completed" link)
|
||||
* @todo fix: custom (i.e. presets) menus are not highlighted
|
||||
*/
|
||||
function admin_menu_multiple_status() {
|
||||
// Remove "Coupons" menu (to get "Orders" menus on top)
|
||||
$coupons_menu = remove_submenu_page( 'woocommerce', 'edit.php?post_type=shop_coupon' );
|
||||
// Maybe remove original "Orders" menu
|
||||
if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_admin_menu_remove_original', 'no' ) ) {
|
||||
remove_submenu_page( 'woocommerce', 'edit.php?post_type=shop_order' );
|
||||
}
|
||||
// Add presets
|
||||
$titles = get_option( 'wcj_order_admin_list_multiple_status_presets_titles', array() );
|
||||
$statuses = get_option( 'wcj_order_admin_list_multiple_status_presets_statuses', array() );
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_order_admin_list_multiple_status_presets_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( ! empty( $titles[ $i ] ) && ! empty( $statuses[ $i ] ) ) {
|
||||
$menu_slug = 'edit.php?post_type=shop_order';
|
||||
foreach ( $statuses[ $i ] as $x => $status ) {
|
||||
$menu_slug .= "&wcj_admin_filter_statuses[{$x}]={$status}";
|
||||
}
|
||||
$orders_count_html = '';
|
||||
if ( 'yes' === get_option( 'wcj_order_admin_list_multiple_status_admin_menu_counter', 'no' ) ) {
|
||||
$order_count = 0;
|
||||
foreach ( $statuses[ $i ] as $x => $status ) {
|
||||
$order_count += wc_orders_count( substr( $status, 3 ) );
|
||||
}
|
||||
$orders_count_html = ' <span class="awaiting-mod update-plugins count-' . esc_attr( $order_count ) . ' wcj-order-count-wrapper"><span class="wcj-order-count">' . number_format_i18n( $order_count ) . '</span></span>'; // WPCS: override ok.
|
||||
}
|
||||
add_submenu_page( 'woocommerce', $titles[ $i ], $titles[ $i ] . $orders_count_html, 'edit_shop_orders', $menu_slug );
|
||||
}
|
||||
}
|
||||
// Re-add "Coupons" menu
|
||||
add_submenu_page( 'woocommerce', $coupons_menu[0], $coupons_menu[3], $coupons_menu[1], $coupons_menu[2] );
|
||||
}
|
||||
|
||||
/**
|
||||
* shop_order_pre_get_posts_order_by_column.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo add sortable to "Billing Country" and "Currency Code"
|
||||
* @todo move custom columns section (probably with reordering and multiple status sections) to new module (e.g. (Admin) Order(s) List) - same with products custom columns
|
||||
* @todo (maybe) add filtering to custom columns (as it's done for "Billing Country" and "Currency Code")
|
||||
*/
|
||||
function shop_order_pre_get_posts_order_by_column( $query ) {
|
||||
if (
|
||||
$query->is_main_query() &&
|
||||
( $orderby = $query->get( 'orderby' ) ) &&
|
||||
isset( $query->query['post_type'] ) && 'shop_order' === $query->query['post_type'] &&
|
||||
isset( $query->is_admin ) && 1 == $query->is_admin
|
||||
) {
|
||||
if ( 'wcj_orders_custom_column_' === substr( $orderby, 0, 25 ) ) {
|
||||
$index = substr( $orderby, 25 );
|
||||
$query->set( 'orderby', get_option( 'wcj_orders_list_custom_columns_sortable_' . $index, 'no' ) ); // 'meta_value' or 'meta_value_num'
|
||||
$query->set( 'meta_key', get_option( 'wcj_orders_list_custom_columns_sortable_key_' . $index, '' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make columns sortable.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @param array $columns
|
||||
* @return array
|
||||
*/
|
||||
function shop_order_sortable_columns( $columns ) {
|
||||
$custom = array();
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_orders_list_custom_columns_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_enabled_' . $i, 'no' ) ) {
|
||||
if ( 'no' != get_option( 'wcj_orders_list_custom_columns_sortable_' . $i, 'no' ) && '' != get_option( 'wcj_orders_list_custom_columns_sortable_key_' . $i, '' ) ) {
|
||||
$custom[ 'wcj_orders_custom_column_' . $i ] = 'wcj_orders_custom_column_' . $i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ( ! empty( $custom ) ? wp_parse_args( $custom, $columns ) : $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_default_statuses_menu.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function hide_default_statuses_menu() {
|
||||
echo '<style>body.post-type-shop_order ul.subsubsub {display: none !important;}</style>';
|
||||
}
|
||||
|
||||
/**
|
||||
* get_orders_default_columns_in_order.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function get_orders_default_columns_in_order() {
|
||||
$columns = array(
|
||||
'cb',
|
||||
'order_status',
|
||||
'order_title',
|
||||
'order_items',
|
||||
'billing_address',
|
||||
'shipping_address',
|
||||
'customer_message',
|
||||
'order_notes',
|
||||
'order_date',
|
||||
'order_total',
|
||||
'order_actions',
|
||||
);
|
||||
return implode( PHP_EOL, $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_shop_order_multiple_statuses_not_completed_link.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function add_shop_order_multiple_statuses_not_completed_link( $views ) {
|
||||
global $wp_query;
|
||||
if ( ! current_user_can( 'edit_others_pages' ) ) {
|
||||
return $views;
|
||||
}
|
||||
$all_not_completed_statuses = wc_get_order_statuses();
|
||||
unset( $all_not_completed_statuses['wc-completed'] );
|
||||
$all_not_completed_statuses = array_keys( $all_not_completed_statuses );
|
||||
$all_not_completed_statuses_param = urlencode( implode( ',', $all_not_completed_statuses ) );
|
||||
$class = ( isset( $wp_query->query['post_status'] ) && is_array( $wp_query->query['post_status'] ) && $all_not_completed_statuses === $wp_query->query['post_status'] ) ? 'current' : '';
|
||||
$query_string = remove_query_arg( array( 'post_status', 'wcj_admin_filter_statuses' ) );
|
||||
$query_string = add_query_arg( 'post_status', $all_not_completed_statuses_param, $query_string );
|
||||
$views['wcj_statuses_not_completed'] = '<a href="' . esc_url( $query_string ) . '" class="' . esc_attr( $class ) . '">' . __( 'Not Completed', 'woocommerce-jetpack' ) . '</a>';
|
||||
return $views;
|
||||
}
|
||||
|
||||
/**
|
||||
* filter_shop_order_multiple_statuses_not_completed_link.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function filter_shop_order_multiple_statuses_not_completed_link( $query ) {
|
||||
if ( false !== strpos( $_SERVER['REQUEST_URI'], '/wp-admin/edit.php' ) && isset( $_GET['post_type'] ) && 'shop_order' === $_GET['post_type'] ) {
|
||||
if ( current_user_can( 'edit_others_pages' ) ) {
|
||||
if ( isset( $_GET['post_status'] ) && false !== strpos( $_GET['post_status'], ',' ) ) {
|
||||
$post_statuses = explode( ',', $_GET['post_status'] );
|
||||
$query->query['post_status'] = $post_statuses;
|
||||
$query->query_vars['post_status'] = $post_statuses;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* multiple_shop_order_statuses.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function multiple_shop_order_statuses( $type ) {
|
||||
$checked_post_statuses = isset( $_GET['wcj_admin_filter_statuses'] ) ? $_GET['wcj_admin_filter_statuses'] : array();
|
||||
$html = '';
|
||||
$html .= ( 'checkboxes' === $type ) ?
|
||||
'<span id="wcj_admin_filter_shop_order_statuses">' :
|
||||
'<select multiple name="wcj_admin_filter_statuses[]" id="wcj_admin_filter_shop_order_statuses" class="chosen_select">';
|
||||
$num_posts = wp_count_posts( 'shop_order', 'readable' );
|
||||
foreach ( array_merge( wc_get_order_statuses(), array( 'trash' => __( 'Trash', 'woocommerce-jetpack' ) ) ) as $status_id => $status_title ) {
|
||||
$total_number = ( isset( $num_posts->{$status_id} ) ) ? $num_posts->{$status_id} : 0;
|
||||
if ( $total_number > 0 ) {
|
||||
$html .= ( 'checkboxes' === $type ) ?
|
||||
'<input type="checkbox" name="wcj_admin_filter_statuses[]" style="width:16px;height:16px;" value="' . $status_id . '"' .
|
||||
checked( in_array( $status_id, $checked_post_statuses ), true, false ) . '>' . $status_title . ' (' . $total_number . ') ' :
|
||||
'<option value="' . $status_id . '"' . selected( in_array( $status_id, $checked_post_statuses ), true, false ) . '>' .
|
||||
$status_title . ' (' . $total_number . ') ' . '</option>';
|
||||
}
|
||||
}
|
||||
$html .= ( 'checkboxes' === $type ) ?
|
||||
'</span>' :
|
||||
'</select>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_shop_order_multiple_statuses.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function add_shop_order_multiple_statuses( $post_type, $which ) {
|
||||
if ( 'shop_order' === $post_type ) {
|
||||
echo $this->multiple_shop_order_statuses( get_option( 'wcj_order_admin_list_multiple_status_filter', 'no' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* filter_shop_order_multiple_statuses.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function filter_shop_order_multiple_statuses( $query ) {
|
||||
if ( false !== strpos( $_SERVER['REQUEST_URI'], '/wp-admin/edit.php' ) && isset( $_GET['post_type'] ) && 'shop_order' === $_GET['post_type'] ) {
|
||||
if ( current_user_can( 'edit_others_pages' ) ) {
|
||||
if ( isset( $_GET['wcj_admin_filter_statuses'] ) ) {
|
||||
$post_statuses = $_GET['wcj_admin_filter_statuses'];
|
||||
$query->query['post_status'] = $post_statuses;
|
||||
$query->query_vars['post_status'] = $post_statuses;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the orders in admin based on options.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @access public
|
||||
* @param mixed $query
|
||||
* @return void
|
||||
*/
|
||||
function parse_query( $query ) {
|
||||
global $typenow, $wp_query;
|
||||
if ( $typenow != 'shop_order' ) {
|
||||
return;
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) && isset( $_GET['country'] ) && 'all' != $_GET['country'] ) {
|
||||
$query->query_vars['meta_query'][] = array(
|
||||
'key' => '_billing_country',
|
||||
'value' => $_GET['country'],
|
||||
);
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) && isset( $_GET['currency'] ) && 'all' != $_GET['currency'] ) {
|
||||
$query->query_vars['meta_query'][] = array(
|
||||
'key' => '_order_currency',
|
||||
'value' => $_GET['currency'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters for post types.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function restrict_manage_posts() {
|
||||
global $typenow, $wp_query;
|
||||
if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ) ) ) {
|
||||
if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) ) {
|
||||
$selected_coutry = isset( $_GET['country'] ) ? $_GET['country'] : 'all';
|
||||
$countries = array_merge( array( 'all' => __( 'All countries', 'woocommerce-jetpack' ) ), wcj_get_countries() );
|
||||
echo '<select id="country" name="country">';
|
||||
foreach ( $countries as $code => $name ) {
|
||||
echo '<option value="' . $code . '" ' . selected( $code, $selected_coutry, false ) . '>' . $name . '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
|
||||
$selected_currency = isset( $_GET['currency'] ) ? $_GET['currency'] : 'all';
|
||||
$currencies = array_merge( array( 'all' => __( 'All currencies', 'woocommerce-jetpack' ) ), wcj_get_currencies_names_and_symbols() );
|
||||
echo '<select id="currency" name="currency">';
|
||||
foreach ( $currencies as $code => $name ) {
|
||||
echo '<option value="' . $code . '" ' . selected( $code, $selected_currency, false ) . '>' . $name . '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rearange_order_columns.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @version 2.5.7
|
||||
*/
|
||||
function rearange_order_columns( $columns ) {
|
||||
$reordered_columns = get_option( 'wcj_order_admin_list_columns_order', $this->get_orders_default_columns_in_order() );
|
||||
$reordered_columns = explode( PHP_EOL, $reordered_columns );
|
||||
$reordered_columns_result = array();
|
||||
if ( ! empty( $reordered_columns ) ) {
|
||||
foreach ( $reordered_columns as $column_id ) {
|
||||
$column_id = str_replace( "\n", '', $column_id );
|
||||
$column_id = str_replace( "\r", '', $column_id );
|
||||
if ( '' != $column_id && isset( $columns[ $column_id ] ) ) {
|
||||
$reordered_columns_result[ $column_id ] = $columns[ $column_id ];
|
||||
unset( $columns[ $column_id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_merge( $reordered_columns_result, $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_order_columns.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function add_order_columns( $columns ) {
|
||||
if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) ) {
|
||||
$columns['country'] = __( 'Billing Country', 'woocommerce-jetpack' );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
|
||||
$columns['currency'] = __( 'Currency Code', 'woocommerce-jetpack' );
|
||||
}
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_orders_list_custom_columns_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_enabled_' . $i, 'no' ) ) {
|
||||
$columns[ 'wcj_orders_custom_column_' . $i ] = get_option( 'wcj_orders_list_custom_columns_label_' . $i, '' );
|
||||
}
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output custom columns for orders
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @param string $column
|
||||
*/
|
||||
function render_order_column( $column ) {
|
||||
if ( 'country' === $column && 'yes' === get_option( 'wcj_orders_list_custom_columns_country', 'no' ) ) {
|
||||
$country_code = do_shortcode( '[wcj_order_checkout_field field_id="billing_country"]' );
|
||||
echo ( 2 == strlen( $country_code ) )
|
||||
? wcj_get_country_flag_by_code( $country_code ) . ' ' . wcj_get_country_name_by_code( $country_code )
|
||||
: wcj_get_country_name_by_code( $country_code );
|
||||
} elseif ( 'currency' === $column && 'yes' === get_option( 'wcj_orders_list_custom_columns_currency', 'no' ) ) {
|
||||
echo do_shortcode( '[wcj_order_currency]' );
|
||||
} else {
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_orders_list_custom_columns_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_orders_list_custom_columns_enabled_' . $i, 'no' ) ) {
|
||||
if ( 'wcj_orders_custom_column_' . $i === $column ) {
|
||||
echo do_shortcode( get_option( 'wcj_orders_list_custom_columns_value_' . $i, '' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Admin_Orders_List();
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Admin Products List
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Admin_Products_List' ) ) :
|
||||
|
||||
class WCJ_Admin_Products_List extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'admin_products_list';
|
||||
$this->short_desc = __( 'Admin Products List', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Customize admin products list.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-admin-products-list';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// Admin list - custom columns
|
||||
if ( 'yes' === get_option( 'wcj_products_admin_list_custom_columns_enabled', 'no' ) ) {
|
||||
add_filter( 'manage_edit-product_columns', array( $this, 'add_product_columns' ), PHP_INT_MAX );
|
||||
add_action( 'manage_product_posts_custom_column', array( $this, 'render_product_column' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Admin list - columns order
|
||||
if ( 'yes' === get_option( 'wcj_products_admin_list_columns_order_enabled', 'no' ) ) {
|
||||
add_filter( 'manage_edit-product_columns', array( $this, 'rearange_product_columns' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rearange_product_columns.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function rearange_product_columns( $columns ) {
|
||||
$reordered_columns = get_option( 'wcj_products_admin_list_columns_order', $this->get_products_default_columns_in_order() );
|
||||
$reordered_columns = explode( PHP_EOL, $reordered_columns );
|
||||
$reordered_columns_result = array();
|
||||
if ( ! empty( $reordered_columns ) ) {
|
||||
foreach ( $reordered_columns as $column_id ) {
|
||||
$column_id = str_replace( "\n", '', $column_id );
|
||||
$column_id = str_replace( "\r", '', $column_id );
|
||||
if ( '' != $column_id && isset( $columns[ $column_id ] ) ) {
|
||||
$reordered_columns_result[ $column_id ] = $columns[ $column_id ];
|
||||
unset( $columns[ $column_id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_merge( $reordered_columns_result, $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* get_products_default_columns_in_order.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function get_products_default_columns_in_order() {
|
||||
$columns = array(
|
||||
'cb',
|
||||
'thumb',
|
||||
'name',
|
||||
'sku',
|
||||
'is_in_stock',
|
||||
'price',
|
||||
'product_cat',
|
||||
'product_tag',
|
||||
'featured',
|
||||
'product_type',
|
||||
'date',
|
||||
);
|
||||
return implode( PHP_EOL, $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_product_columns.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function add_product_columns( $columns ) {
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_products_admin_list_custom_columns_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_products_admin_list_custom_columns_enabled_' . $i, 'no' ) ) {
|
||||
$columns[ 'wcj_products_custom_column_' . $i ] = get_option( 'wcj_products_admin_list_custom_columns_label_' . $i, '' );
|
||||
}
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* render_product_column.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function render_product_column( $column ) {
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_products_admin_list_custom_columns_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_products_admin_list_custom_columns_enabled_' . $i, 'no' ) ) {
|
||||
if ( 'wcj_products_custom_column_' . $i === $column ) {
|
||||
echo do_shortcode( get_option( 'wcj_products_admin_list_custom_columns_value_' . $i, '' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Admin_Products_List();
|
||||
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Admin Tools
|
||||
*
|
||||
* @version 3.4.3
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Admin_Tools' ) ) :
|
||||
|
||||
class WCJ_Admin_Tools extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @todo (maybe) add editable (product and order) metas
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'admin_tools';
|
||||
$this->short_desc = __( 'Admin Tools', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Booster for WooCommerce debug and log tools.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-booster-admin-tools';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'admin_tools' => array(
|
||||
'title' => __( 'Admin Tools', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Log.', 'woocommerce-jetpack' ),
|
||||
'tab_title' => __( 'Log', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
|
||||
$this->current_php_memory_limit = '';
|
||||
$this->current_php_time_limit = '';
|
||||
if ( $this->is_enabled() ) {
|
||||
// PHP Memory Limit
|
||||
if ( 0 != ( $php_memory_limit = get_option( 'wcj_admin_tools_php_memory_limit', 0 ) ) ) {
|
||||
ini_set( 'memory_limit', $php_memory_limit . 'M' );
|
||||
}
|
||||
$this->current_php_memory_limit = sprintf( ' ' . __( 'Current PHP memory limit: %s.', 'woocommerce-jetpack' ), ini_get( 'memory_limit' ) );
|
||||
// PHP Time Limit
|
||||
if ( 0 != ( $php_time_limit = get_option( 'wcj_admin_tools_php_time_limit', 0 ) ) ) {
|
||||
set_time_limit( $php_time_limit );
|
||||
}
|
||||
$this->current_php_time_limit = sprintf( ' ' . __( 'Current PHP time limit: %s seconds.', 'woocommerce-jetpack' ), ini_get( 'max_execution_time' ) );
|
||||
// Order Meta
|
||||
if ( 'yes' === get_option( 'wcj_admin_tools_show_order_meta_enabled', 'no' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_order_meta_meta_box' ) );
|
||||
}
|
||||
// Product Meta
|
||||
if ( 'yes' === get_option( 'wcj_admin_tools_show_product_meta_enabled', 'no' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_product_meta_meta_box' ) );
|
||||
}
|
||||
// Variable Product Pricing
|
||||
if ( 'yes' === get_option( 'wcj_admin_tools_variable_product_pricing_table_enabled', 'no' ) ) {
|
||||
add_action( 'admin_head', array( $this, 'make_original_variable_product_pricing_readonly' ) );
|
||||
add_action( 'add_meta_boxes', array( $this, 'maybe_add_variable_product_pricing_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* make_original_variable_product_pricing_readonly.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
* @todo this is not really making fields readonly (e.g. field is still editable via keyboard tab button)
|
||||
*/
|
||||
function make_original_variable_product_pricing_readonly() {
|
||||
echo '<style>
|
||||
div.variable_pricing input.wc_input_price {
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>';
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_variable_product_pricing_meta_box.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function maybe_add_variable_product_pricing_meta_box() {
|
||||
if ( ( $_product = wc_get_product() ) && $_product->is_type( 'variable' ) ) {
|
||||
parent::add_meta_box();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_product_meta_meta_box.
|
||||
*
|
||||
* @version 2.5.8
|
||||
* @since 2.5.8
|
||||
*/
|
||||
function add_product_meta_meta_box() {
|
||||
add_meta_box(
|
||||
'wcj-admin-tools-product-meta',
|
||||
__( 'Product Meta', 'woocommerce-jetpack' ),
|
||||
array( $this, 'create_meta_meta_box' ),
|
||||
'product',
|
||||
'normal',
|
||||
'low'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* add_order_meta_meta_box.
|
||||
*
|
||||
* @version 2.5.8
|
||||
* @since 2.5.8
|
||||
*/
|
||||
function add_order_meta_meta_box() {
|
||||
add_meta_box(
|
||||
'wcj-admin-tools-order-meta',
|
||||
__( 'Order Meta', 'woocommerce-jetpack' ),
|
||||
array( $this, 'create_meta_meta_box' ),
|
||||
'shop_order',
|
||||
'normal',
|
||||
'low'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_meta_meta_box.
|
||||
*
|
||||
* @version 3.2.1
|
||||
* @since 2.5.8
|
||||
*/
|
||||
function create_meta_meta_box( $post ) {
|
||||
$html = '';
|
||||
$post_id = get_the_ID();
|
||||
// Meta
|
||||
$meta = get_post_meta( $post_id );
|
||||
$table_data = array();
|
||||
foreach ( $meta as $meta_key => $meta_values ) {
|
||||
$table_data[] = array( $meta_key, esc_html( print_r( maybe_unserialize( $meta_values[0] ), true ) ) );
|
||||
}
|
||||
$html .= wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'vertical' ) );
|
||||
// Items Meta (for orders only)
|
||||
if ( 'shop_order' === $post->post_type ) {
|
||||
$_order = wc_get_order( $post_id );
|
||||
$table_data = array();
|
||||
foreach ( $_order->get_items() as $item_key => $item ) {
|
||||
foreach ( $item['item_meta'] as $item_meta_key => $item_meta_value ) {
|
||||
$table_data[] = array( $item_key, $item_meta_key, esc_html( print_r( maybe_unserialize( $item_meta_value ), true ) ) );
|
||||
}
|
||||
}
|
||||
if ( ! empty( $table_data ) ) {
|
||||
$html .= '<h3>' . __( 'Order Items Meta', 'woocommerce-jetpack' ) . '</h3>';
|
||||
$table_data = array_merge(
|
||||
array( array( __( 'Item Key', 'woocommerce-jetpack' ), __( 'Item Meta Key', 'woocommerce-jetpack' ), __( 'Item Meta Value', 'woocommerce-jetpack' ) ) ),
|
||||
$table_data
|
||||
);
|
||||
$html .= wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'horizontal' ) );
|
||||
}
|
||||
}
|
||||
// Output
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* create_admin_tools_tool.
|
||||
*
|
||||
* @version 3.3.0
|
||||
*/
|
||||
function create_admin_tools_tool() {
|
||||
// Delete log
|
||||
if ( isset( $_GET['wcj_delete_log'] ) && wcj_is_user_role( 'administrator' ) ) {
|
||||
update_option( 'wcj_log', '' );
|
||||
if ( wp_safe_redirect( remove_query_arg( 'wcj_delete_log' ) ) ) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
// Header
|
||||
$the_tools = '';
|
||||
$the_tools .= $this->get_tool_header_html( 'admin_tools' );
|
||||
$the_tools .= '<p><a href="' . add_query_arg( 'wcj_delete_log', '1' ) . '">' . __( 'Delete Log', 'woocommerce-jetpack' ) . '</a></p>';
|
||||
// Log
|
||||
$the_log = '';
|
||||
$the_log .= '<p style="font-style:italic;color:gray;">' . sprintf( __( 'Now: %s', 'woocommerce-jetpack' ), date( 'Y-m-d H:i:s' ) ) . '</p>';
|
||||
if ( '' != ( $log = get_option( 'wcj_log', '' ) ) ) {
|
||||
$the_log .= '<pre style="color:green;background-color:black;padding:5px;">' . $log . '</pre>';
|
||||
} else {
|
||||
$the_log .= '<p style="font-style:italic;color:gray;">' . __( 'Log is empty.', 'woocommerce-jetpack' ) . '</p>';
|
||||
}
|
||||
// Final output
|
||||
$html = '';
|
||||
$html .= '<div class="wrap">';
|
||||
$html .= '<p>' . $the_tools . '</p>';
|
||||
$html .= '<p>' . $the_log . '</p>';
|
||||
$html .= '</div>';
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_system_info_table_array.
|
||||
*
|
||||
* @version 3.4.3
|
||||
* @since 2.5.7
|
||||
* @todo (maybe) 'DB_NAME', 'DB_USER', 'DB_PASSWORD', 'DB_HOST', 'DB_CHARSET', 'DB_COLLATE'
|
||||
*/
|
||||
function get_system_info_table_array() {
|
||||
$system_info = array();
|
||||
$constants_array = array(
|
||||
'WP_MEMORY_LIMIT',
|
||||
'WP_MAX_MEMORY_LIMIT',
|
||||
'WP_DEBUG',
|
||||
'ABSPATH',
|
||||
'DISABLE_WP_CRON',
|
||||
'WP_CRON_LOCK_TIMEOUT',
|
||||
'WCJ_WC_VERSION',
|
||||
'WCJ_SESSION_TYPE',
|
||||
);
|
||||
foreach ( $constants_array as $the_constant ) {
|
||||
$system_info[] = array( $the_constant, ( defined( $the_constant ) ? constant( $the_constant ) : __( 'NOT DEFINED', 'woocommerce-jetpack' ) ) );
|
||||
}
|
||||
if ( isset( $_GET['wcj_debug'] ) ) {
|
||||
foreach ( $_SERVER as $server_var_id => $server_var_value ) {
|
||||
$system_info[] = array( $server_var_id, $server_var_value );
|
||||
}
|
||||
}
|
||||
return $system_info;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Admin_Tools();
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Breadcrumbs
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.9.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Breadcrumbs' ) ) :
|
||||
|
||||
class WCJ_Breadcrumbs extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo recheck filter: `woocommerce_get_breadcrumb`
|
||||
* @todo recheck filter: `woocommerce_structured_data_breadcrumblist`; action: `woocommerce_breadcrumb`;
|
||||
* @todo recheck filter: `woocommerce_breadcrumb_defaults`; action: `woocommerce_breadcrumb`
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'breadcrumbs';
|
||||
$this->short_desc = __( 'Breadcrumbs', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Customize WooCommerce breadcrumbs.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-breadcrumbs';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// Hide Breadcrumbs
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_breadcrumbs_hide', 'no' ) ) ) {
|
||||
add_filter( 'woocommerce_get_breadcrumb', '__return_false', PHP_INT_MAX );
|
||||
add_action( 'wp_head', array( $this, 'hide_breadcrumbs_with_css' ) );
|
||||
add_action( 'wp_loaded', array( $this, 'hide_breadcrumbs_by_removing_action' ), PHP_INT_MAX );
|
||||
}
|
||||
// Home URL
|
||||
if ( 'yes' === get_option( 'wcj_breadcrumbs_change_home_url_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_breadcrumb_home_url', array( $this, 'change_home_url' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_home_url.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function change_home_url( $_url ) {
|
||||
return get_option( 'wcj_breadcrumbs_home_url', home_url() );
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_breadcrumbs_with_css.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) option to add custom identifiers
|
||||
* @todo (maybe) add more identifiers
|
||||
*/
|
||||
function hide_breadcrumbs_with_css() {
|
||||
$identifiers = array(
|
||||
'.woocommerce-breadcrumb',
|
||||
'.woo-breadcrumbs',
|
||||
'.breadcrumbs',
|
||||
'.breadcrumb',
|
||||
'#breadcrumbs',
|
||||
'.breadcrumbs-wrapper',
|
||||
);
|
||||
echo '<style>' . implode( ', ', $identifiers ) . ' { display: none !important; }' . '</style>';
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_breadcrumbs_by_removing_action.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @see `add_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20, 0 );`
|
||||
*/
|
||||
function hide_breadcrumbs_by_removing_action() {
|
||||
remove_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Breadcrumbs();
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Call for Price
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Call_For_Price' ) ) :
|
||||
|
||||
class WCJ_Call_For_Price extends WCJ_module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @todo add "per product type" labels
|
||||
* @todo add "per product" labels
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'call_for_price';
|
||||
$this->short_desc = __( 'Call for Price', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Create any custom price label for all products with empty price.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-call-for-price';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_get_variation_prices_hash', array( $this, 'get_variation_prices_hash' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'init', array( $this, 'add_empty_price_hooks' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_sale_flash', array( $this, 'hide_sales_flash' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'admin_head', array( $this, 'hide_variation_price_required_placeholder' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_variation_is_visible', array( $this, 'make_variation_visible_with_empty_price' ), PHP_INT_MAX, 4 );
|
||||
add_action( 'wp_head', array( $this, 'hide_disabled_variation_add_to_cart_button' ) );
|
||||
if ( 'yes' === get_option( 'wcj_call_for_price_make_all_empty', 'no' ) ) {
|
||||
add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'make_empty_price' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_variation_prices_price', array( $this, 'make_empty_price' ), PHP_INT_MAX, 2 );
|
||||
if ( ! WCJ_IS_WC_VERSION_BELOW_3 ) {
|
||||
add_filter( 'woocommerce_product_variation_get_price', array( $this, 'make_empty_price' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_variation_prices_hash.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
* @todo not sure if this is really needed
|
||||
*/
|
||||
function get_variation_prices_hash( $price_hash, $_product, $display ) {
|
||||
$price_hash['wcj_call_for_price'] = array(
|
||||
get_option( 'wcj_call_for_price_make_all_empty', 'no' ),
|
||||
);
|
||||
return $price_hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* make_variation_visible_with_empty_price.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
* @return bool
|
||||
*/
|
||||
function make_variation_visible_with_empty_price( $visible, $_variation_id, $_id, $_product ) {
|
||||
if ( '' === $_product->get_price() ) {
|
||||
$visible = true;
|
||||
// Published == enabled checkbox
|
||||
if ( get_post_status( $_variation_id ) != 'publish' ) {
|
||||
$visible = false;
|
||||
}
|
||||
}
|
||||
return $visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_disabled_variation_add_to_cart_button.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function hide_disabled_variation_add_to_cart_button() {
|
||||
echo '<style>div.woocommerce-variation-add-to-cart-disabled { display: none ! important; }</style>';
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_variation_price_required_placeholder.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function hide_variation_price_required_placeholder() {
|
||||
echo '<style>
|
||||
div.variable_pricing input.wc_input_price::-webkit-input-placeholder { /* WebKit browsers */
|
||||
color: transparent;
|
||||
}
|
||||
div.variable_pricing input.wc_input_price:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
|
||||
color: transparent;
|
||||
}
|
||||
div.variable_pricing input.wc_input_price::-moz-placeholder { /* Mozilla Firefox 19+ */
|
||||
color: transparent;
|
||||
}
|
||||
div.variable_pricing input.wc_input_price:-ms-input-placeholder { /* Internet Explorer 10+ */
|
||||
color: transparent;
|
||||
}
|
||||
</style>';
|
||||
}
|
||||
|
||||
/**
|
||||
* make_empty_price.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function make_empty_price( $price, $_product ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* add_empty_price_hooks.
|
||||
*
|
||||
* @version 3.2.4
|
||||
*/
|
||||
function add_empty_price_hooks() {
|
||||
add_filter( 'woocommerce_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_variable_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_grouped_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_variation_empty_price_html', array( $this, 'on_empty_price' ), PHP_INT_MAX, 2 ); // Only in < WC3
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide "sales" icon for empty price products.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @todo recheck if we really need this
|
||||
*/
|
||||
function hide_sales_flash( $onsale_html, $post, $product ) {
|
||||
if ( 'yes' === get_option( 'wcj_call_for_price_hide_sale_sign', 'yes' ) && '' === $product->get_price() ) {
|
||||
return '';
|
||||
}
|
||||
return $onsale_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* On empty price filter - return the label.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @todo `is_page()`
|
||||
*/
|
||||
function on_empty_price( $price, $_product ) {
|
||||
if ( '' !== get_option( 'wcj_call_for_price_text_variation' ) && $_product->is_type( 'variation' ) ) {
|
||||
return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_variation' ) ) );
|
||||
} elseif ( '' !== get_option( 'wcj_call_for_price_text' ) && is_single( get_the_ID() ) ) {
|
||||
return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text' ) ) );
|
||||
} elseif ( '' !== get_option( 'wcj_call_for_price_text_on_related' ) && is_single() && ! is_single( get_the_ID() ) ) {
|
||||
return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_on_related' ) ) );
|
||||
} elseif ( '' !== get_option( 'wcj_call_for_price_text_on_archive' ) && is_archive() ) {
|
||||
return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_on_archive' ) ) );
|
||||
} elseif ( '' !== get_option( 'wcj_call_for_price_text_on_home' ) && is_front_page() ) {
|
||||
return do_shortcode( apply_filters( 'booster_option', '<strong>Call for price</strong>', get_option( 'wcj_call_for_price_text_on_home' ) ) );
|
||||
} else {
|
||||
return $price;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Call_For_Price();
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Cart Customization
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.7.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Cart_Customization' ) ) :
|
||||
|
||||
class WCJ_Cart_Customization extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'cart_customization';
|
||||
$this->short_desc = __( 'Cart Customization', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Customize WooCommerce cart - hide coupon field; item remove link; change empty cart "Return to shop" button text.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-cart-customization';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// Hide coupon
|
||||
if ( 'yes' === get_option( 'wcj_cart_hide_coupon', 'no' ) ) {
|
||||
add_filter( 'woocommerce_coupons_enabled', array( $this, 'hide_coupon_field_on_cart' ), PHP_INT_MAX );
|
||||
}
|
||||
// Hide item remove link
|
||||
if ( 'yes' === get_option( 'wcj_cart_hide_item_remove_link', 'no' ) ) {
|
||||
add_filter( 'woocommerce_cart_item_remove_link', '__return_empty_string', PHP_INT_MAX );
|
||||
}
|
||||
// Customize "Return to shop" button text
|
||||
if ( 'yes' === get_option( 'wcj_cart_customization_return_to_shop_button_enabled', 'no' ) ) {
|
||||
if ( 'js' === get_option( 'wcj_cart_customization_return_to_shop_button_text_method', 'js' ) ) {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
} else { // 'template'
|
||||
add_filter( 'wc_get_template', array( $this, 'replace_empty_cart_template' ), PHP_INT_MAX, 5 );
|
||||
add_filter( 'wcj_return_to_shop_text', array( $this, 'change_empty_cart_button_text' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
// Customize "Return to shop" button link
|
||||
if ( 'yes' === get_option( 'wcj_cart_customization_return_to_shop_button_link_enabled', 'no' ) ) {
|
||||
add_action( 'woocommerce_return_to_shop_redirect', array( $this, 'change_empty_cart_return_to_shop_link' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_empty_cart_button_text.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function change_empty_cart_button_text( $text ) {
|
||||
return get_option( 'wcj_cart_customization_return_to_shop_button_text', __( 'Return to shop', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* replace_empty_cart_template.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
* @todo fix folder structure in /templates
|
||||
*/
|
||||
function replace_empty_cart_template( $located, $template_name, $args, $template_path, $default_path ) {
|
||||
if ( 'cart/cart-empty.php' == $template_name ) {
|
||||
$located = untrailingslashit( realpath( plugin_dir_path( __FILE__ ) . '/..' ) ) . '/includes/templates/cart-empty.php';
|
||||
}
|
||||
return $located;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_empty_cart_return_to_shop_link.
|
||||
*
|
||||
* @version 3.0.1
|
||||
* @since 3.0.1
|
||||
* @todo (maybe) check if link is not empty
|
||||
*/
|
||||
function change_empty_cart_return_to_shop_link( $link ) {
|
||||
return ( is_cart() ? get_option( 'wcj_cart_customization_return_to_shop_button_link', '' ) : $link );
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_scripts.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
* @todo maybe check `is_cart()`
|
||||
*/
|
||||
function enqueue_scripts() {
|
||||
wp_enqueue_script( 'wcj-cart-customization', wcj_plugin_url() . '/includes/js/wcj-cart-customization.js', array( 'jquery' ), WCJ()->version, false );
|
||||
wp_localize_script( 'wcj-cart-customization', 'wcj_cart_customization', array(
|
||||
'return_to_shop_button_text' => get_option( 'wcj_cart_customization_return_to_shop_button_text', __( 'Return to shop', 'woocommerce' ) ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_coupon_field_on_cart.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function hide_coupon_field_on_cart( $enabled ) {
|
||||
return ( is_cart() ) ? false : $enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Cart_Customization();
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Cart Custom Info
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Cart' ) ) :
|
||||
|
||||
class WCJ_Cart extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'cart';
|
||||
$this->short_desc = __( 'Cart Custom Info', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add custom info to the cart page.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-cart-custom-info';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// Cart items table custom info
|
||||
add_filter( 'woocommerce_cart_item_name', array( $this, 'add_custom_info_to_cart_item_name' ), PHP_INT_MAX, 3 );
|
||||
// Cart custom info
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_cart_custom_info_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++) {
|
||||
add_action(
|
||||
get_option( 'wcj_cart_custom_info_hook_' . $i, 'woocommerce_after_cart_totals' ),
|
||||
array( $this, 'add_cart_custom_info' ),
|
||||
get_option( 'wcj_cart_custom_info_priority_' . $i, 10 )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_info_to_cart_item_name.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.3.9
|
||||
* @todo (maybe) `wc_setup_product_data( $post );`
|
||||
*/
|
||||
function add_custom_info_to_cart_item_name( $product_title, $cart_item, $cart_item_key ) {
|
||||
$custom_content = get_option( 'wcj_cart_custom_info_item' );
|
||||
if ( '' != $custom_content ) {
|
||||
global $post;
|
||||
$product_id = ( ! empty( $cart_item['variation_id'] ) ? $cart_item['variation_id'] : $cart_item['product_id'] );
|
||||
$post = get_post( $product_id );
|
||||
setup_postdata( $post );
|
||||
$product_title .= do_shortcode( $custom_content );
|
||||
wp_reset_postdata();
|
||||
}
|
||||
return $product_title;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_cart_custom_info.
|
||||
*
|
||||
* @version 2.4.6
|
||||
*/
|
||||
function add_cart_custom_info() {
|
||||
$current_filter = current_filter();
|
||||
$current_filter_priority = wcj_current_filter_priority();
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_cart_custom_info_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if (
|
||||
'' != get_option( 'wcj_cart_custom_info_content_' . $i ) &&
|
||||
$current_filter === get_option( 'wcj_cart_custom_info_hook_' . $i, 'woocommerce_after_cart_totals' ) &&
|
||||
$current_filter_priority == get_option( 'wcj_cart_custom_info_priority_' . $i, 10 )
|
||||
) {
|
||||
echo do_shortcode( get_option( 'wcj_cart_custom_info_content_' . $i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Cart();
|
||||
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Checkout Core Fields
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Checkout_Core_Fields' ) ) :
|
||||
|
||||
class WCJ_Checkout_Core_Fields extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @see https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
|
||||
* @todo (maybe) default overrides should be `disable`
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'checkout_core_fields';
|
||||
$this->short_desc = __( 'Checkout Core Fields', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Customize core checkout fields. Disable/enable fields, set required, change labels and/or placeholders etc.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-checkout-core-fields';
|
||||
parent::__construct();
|
||||
|
||||
$this->woocommerce_core_checkout_fields = array(
|
||||
'billing_country',
|
||||
'billing_first_name',
|
||||
'billing_last_name',
|
||||
'billing_company',
|
||||
'billing_address_1',
|
||||
'billing_address_2',
|
||||
'billing_city',
|
||||
'billing_state',
|
||||
'billing_postcode',
|
||||
'billing_email',
|
||||
'billing_phone',
|
||||
'shipping_country',
|
||||
'shipping_first_name',
|
||||
'shipping_last_name',
|
||||
'shipping_company',
|
||||
'shipping_address_1',
|
||||
'shipping_address_2',
|
||||
'shipping_city',
|
||||
'shipping_state',
|
||||
'shipping_postcode',
|
||||
'account_username',
|
||||
'account_password',
|
||||
'account_password-2',
|
||||
'order_comments',
|
||||
);
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_checkout_fields' , array( $this, 'custom_override_checkout_fields' ), PHP_INT_MAX );
|
||||
if ( 'disable' != ( $this->country_locale_override = get_option( 'wcj_checkout_core_fields_override_country_locale_fields', 'billing' ) ) ) {
|
||||
add_filter( 'woocommerce_get_country_locale', array( $this, 'custom_override_country_locale_fields' ), PHP_INT_MAX );
|
||||
}
|
||||
if ( 'disable' != ( $this->default_address_override = get_option( 'wcj_checkout_core_fields_override_default_address_fields', 'billing' ) ) ) {
|
||||
add_filter( 'woocommerce_default_address_fields', array( $this, 'custom_override_default_address_fields' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_override_fields.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.1.0
|
||||
* @todo (maybe) add option to choose `$options_to_override`
|
||||
* @todo (maybe) add to `$options_to_override`: enabled; class;
|
||||
*/
|
||||
function maybe_override_fields( $fields, $override_with_section ) {
|
||||
$options_to_override = array(
|
||||
'label' => array(
|
||||
'default' => '',
|
||||
),
|
||||
'placeholder' => array(
|
||||
'default' => '',
|
||||
),
|
||||
'description' => array(
|
||||
'default' => '',
|
||||
),
|
||||
'priority' => array(
|
||||
'default' => 0,
|
||||
),
|
||||
'required' => array(
|
||||
'default' => 'default',
|
||||
'option_id' => 'is_required',
|
||||
'values' => array(
|
||||
'yes' => true,
|
||||
'no' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
foreach ( $fields as $field_key => $field_values ) {
|
||||
$field = $override_with_section . '_' . $field_key;
|
||||
foreach ( $options_to_override as $option => $option_data ) {
|
||||
$default_value = $option_data['default'];
|
||||
$option_id = ( isset( $option_data['option_id'] ) ? $option_data['option_id'] : $option );
|
||||
$option_id = 'wcj_checkout_fields_' . $field . '_' . $option_id;
|
||||
if ( $default_value != ( $value = get_option( $option_id, $default_value ) ) ) {
|
||||
$value = ( isset( $option_data['values'][ $value ] ) ? $option_data['values'][ $value ] : $value );
|
||||
$fields[ $field_key ][ $option ] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* custom_override_country_locale_fields.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function custom_override_country_locale_fields( $fields ) {
|
||||
foreach ( $fields as $country => $country_fields ) {
|
||||
$fields[ $country ] = $this->maybe_override_fields( $country_fields, $this->country_locale_override );
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* custom_override_default_address_fields.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.3.8
|
||||
*/
|
||||
function custom_override_default_address_fields( $fields ) {
|
||||
return $this->maybe_override_fields( $fields, $this->default_address_override );
|
||||
}
|
||||
|
||||
/**
|
||||
* custom_override_checkout_fields.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @todo add "per products", "per products tags"
|
||||
* @todo (maybe) fix - priority seems to not affect tab order (same in Checkout Custom Fields module)
|
||||
* @todo (maybe) enable if was not enabled by default, i.e. `! isset( $checkout_fields[ $section ][ $field ] )`
|
||||
*/
|
||||
function custom_override_checkout_fields( $checkout_fields ) {
|
||||
foreach ( $this->woocommerce_core_checkout_fields as $field ) {
|
||||
$field_parts = explode( '_', $field, 2 );
|
||||
$section = ( ! empty( $field_parts ) && is_array( $field_parts ) ? $field_parts[0] : '' ); // billing or shipping
|
||||
// enabled
|
||||
if ( 'no' === ( $is_enabled = get_option( 'wcj_checkout_fields_' . $field . '_' . 'is_enabled', 'default' ) ) ) {
|
||||
if ( isset( $checkout_fields[ $section ][ $field ] ) ) {
|
||||
unset( $checkout_fields[ $section ][ $field ] ); // e.g. unset( $checkout_fields['billing']['billing_country'] );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// enabled - per products categories
|
||||
if ( ! $this->is_visible( array(
|
||||
'include_products' => '',
|
||||
'exclude_products' => '',
|
||||
'include_categories' => apply_filters( 'booster_option', '', get_option( 'wcj_checkout_fields_' . $field . '_' . 'cats_incl', '' ) ),
|
||||
'exclude_categories' => apply_filters( 'booster_option', '', get_option( 'wcj_checkout_fields_' . $field . '_' . 'cats_excl', '' ) ),
|
||||
'include_tags' => '',
|
||||
'exclude_tags' => '',
|
||||
) )
|
||||
) {
|
||||
unset( $checkout_fields[ $section ][ $field ] );
|
||||
continue;
|
||||
}
|
||||
if ( isset( $checkout_fields[ $section ][ $field ] ) ) {
|
||||
// required
|
||||
if ( 'default' != ( $is_required = get_option( 'wcj_checkout_fields_' . $field . '_' . 'is_required', 'default' ) ) ) {
|
||||
$checkout_fields[ $section ][ $field ]['required'] = ( 'yes' === $is_required );
|
||||
}
|
||||
// label
|
||||
if ( '' != ( $label = get_option( 'wcj_checkout_fields_' . $field . '_' . 'label', '' ) ) ) {
|
||||
$checkout_fields[ $section ][ $field ]['label'] = $label;
|
||||
}
|
||||
// placeholder
|
||||
if ( '' != ( $placeholder = get_option( 'wcj_checkout_fields_' . $field . '_' . 'placeholder', '' ) ) ) {
|
||||
$checkout_fields[ $section ][ $field ]['placeholder'] = $placeholder;
|
||||
}
|
||||
// description
|
||||
if ( '' != ( $description = get_option( 'wcj_checkout_fields_' . $field . '_' . 'description', '' ) ) ) {
|
||||
$checkout_fields[ $section ][ $field ]['description'] = $description;
|
||||
}
|
||||
// class
|
||||
if ( 'default' != ( $class = get_option( 'wcj_checkout_fields_' . $field . '_' . 'class', 'default' ) ) ) {
|
||||
$checkout_fields[ $section ][ $field ]['class'] = array( $class );
|
||||
}
|
||||
// priority
|
||||
if ( 0 != ( $priority = apply_filters( 'booster_option', 0, get_option( 'wcj_checkout_fields_' . $field . '_' . 'priority', 0 ) ) ) ) {
|
||||
$checkout_fields[ $section ][ $field ]['priority'] = $priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_checkout_core_fields_force_sort_by_priority', 'no' ) ) {
|
||||
$field_sets = array( 'billing', 'shipping', 'account', 'order' );
|
||||
foreach ( $field_sets as $field_set ) {
|
||||
if ( isset( $checkout_fields[ $field_set ] ) ) {
|
||||
uasort( $checkout_fields[ $field_set ], array( $this, 'sort_by_priority' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $checkout_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_visible.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
* @todo (maybe) save `$this->cart_product_ids` array (instead of calling `WC()->cart->get_cart()` for each field)
|
||||
*/
|
||||
function is_visible( $args ) {
|
||||
foreach ( $args as $arg ) {
|
||||
if ( ! empty( $arg ) ) {
|
||||
// At least one arg is filled - checking products in cart
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
if ( ! wcj_is_enabled_for_product( $values['product_id'], $args ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* sort_by_priority.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
*/
|
||||
function sort_by_priority( $a, $b ) {
|
||||
$a = ( isset( $a['priority'] ) ? $a['priority'] : 0 );
|
||||
$b = ( isset( $b['priority'] ) ? $b['priority'] : 0 );
|
||||
if ( $a == $b ) {
|
||||
return 0;
|
||||
}
|
||||
return ( $a < $b ) ? -1 : 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Checkout_Core_Fields();
|
||||
@@ -0,0 +1,642 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Checkout Custom Fields
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Checkout_Custom_Fields' ) ) :
|
||||
|
||||
class WCJ_Checkout_Custom_Fields extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @todo (maybe) check if `'wcj_checkout_custom_field_customer_meta_fields_' . $i` option should affect `add_default_checkout_custom_fields`
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'checkout_custom_fields';
|
||||
$this->short_desc = __( 'Checkout Custom Fields', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add custom fields to the checkout page.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-checkout-custom-fields';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
add_filter( 'woocommerce_checkout_fields', array( $this, 'add_custom_checkout_fields' ), PHP_INT_MAX );
|
||||
|
||||
add_action( 'woocommerce_admin_billing_fields', array( $this, 'add_custom_billing_fields_to_admin_order_display' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_admin_shipping_fields', array( $this, 'add_custom_shipping_fields_to_admin_order_display' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_admin_order_data_after_shipping_address', array( $this, 'add_custom_order_and_account_fields_to_admin_order_display' ), PHP_INT_MAX );
|
||||
|
||||
if ( 'yes' === get_option( 'wcj_checkout_custom_fields_add_to_order_received', 'yes' ) ) {
|
||||
add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_custom_fields_to_view_order_and_thankyou_pages' ), PHP_INT_MAX );
|
||||
}
|
||||
add_action( 'woocommerce_email_after_order_table', array( $this, 'add_custom_fields_to_emails' ), PHP_INT_MAX, 2 );
|
||||
|
||||
add_filter( 'woo_ce_order_fields', array( $this, 'add_custom_fields_to_store_exporter' ) );
|
||||
add_filter( 'woo_ce_order', array( $this, 'add_custom_fields_to_store_exporter_order' ), PHP_INT_MAX, 2 );
|
||||
|
||||
add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'update_custom_checkout_fields_order_meta' ) );
|
||||
|
||||
// add_action( 'woocommerce_order_formatted_shipping_address', array( $this, 'add_custom_shipping_fields_to_formatted_address' ), PHP_INT_MAX, 2 );
|
||||
|
||||
// add_filter( 'woocommerce_form_field_' . 'number', array( $this, 'woocommerce_form_field_type_number' ), PHP_INT_MAX, 4 );
|
||||
add_filter( 'woocommerce_form_field_' . 'text', array( $this, 'woocommerce_form_field_type_number' ), PHP_INT_MAX, 4 );
|
||||
|
||||
add_filter( 'woocommerce_customer_meta_fields', array( $this, 'add_checkout_custom_fields_customer_meta_fields' ) );
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
|
||||
$the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
|
||||
$the_key = 'wcj_checkout_field_' . $i;
|
||||
$the_name = $the_section . '_' . $the_key;
|
||||
add_filter( 'default_checkout_' . $the_name, array( $this, 'add_default_checkout_custom_fields' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
// select2 script
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_scripts' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_enqueue_scripts.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.2.0
|
||||
*/
|
||||
function maybe_enqueue_scripts( $fields ) {
|
||||
if ( is_checkout() ) {
|
||||
$select2_fields = array();
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i, 'no' ) ) {
|
||||
if ( 'select' === get_option( 'wcj_checkout_custom_field_type_' . $i, 'text' ) ) {
|
||||
if ( 'yes' === get_option( 'wcj_checkout_custom_field_select_select2_' . $i, 'no' ) ) {
|
||||
$select2_fields[] = array(
|
||||
'field_id' => get_option( 'wcj_checkout_custom_field_section_' . $i, 'billing' ) . '_' . 'wcj_checkout_field_' . $i,
|
||||
'minimumInputLength' => get_option( 'wcj_checkout_custom_field_select_select2_min_input_length' . $i, 0 ),
|
||||
'maximumInputLength' => get_option( 'wcj_checkout_custom_field_select_select2_max_input_length' . $i, 0 ),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! empty( $select2_fields ) ) {
|
||||
wp_enqueue_script(
|
||||
'wcj-checkout-custom-fields',
|
||||
wcj_plugin_url() . '/includes/js/wcj-checkout-custom-fields.js',
|
||||
array( 'jquery' ),
|
||||
WCJ()->version,
|
||||
true
|
||||
);
|
||||
wp_localize_script(
|
||||
'wcj-checkout-custom-fields',
|
||||
'wcj_checkout_custom_fields',
|
||||
array(
|
||||
'select2_fields' => $select2_fields,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_checkout_custom_fields_customer_meta_fields.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.4.5
|
||||
*/
|
||||
function add_checkout_custom_fields_customer_meta_fields( $fields ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
|
||||
if ( 'no' === get_option( 'wcj_checkout_custom_field_customer_meta_fields_' . $i, 'yes' ) ) {
|
||||
continue;
|
||||
}
|
||||
$the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
|
||||
$the_key = 'wcj_checkout_field_' . $i;
|
||||
$the_name = $the_section . '_' . $the_key;
|
||||
$fields[ $the_section ]['fields'][ $the_name ] = array(
|
||||
'label' => get_option( 'wcj_checkout_custom_field_label_' . $i ),
|
||||
'description' => '',
|
||||
);
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_default_checkout_custom_fields.
|
||||
*
|
||||
* @version 2.4.5
|
||||
* @since 2.4.5
|
||||
*/
|
||||
function add_default_checkout_custom_fields( $default_value, $field_key ) {
|
||||
if ( is_user_logged_in() ) {
|
||||
$current_user = wp_get_current_user();
|
||||
if ( $meta = get_user_meta( $current_user->ID, $field_key, true ) ) {
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
return $default_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* woocommerce_form_field_type_number.
|
||||
*
|
||||
* @version 2.3.0
|
||||
* @since 2.3.0
|
||||
*/
|
||||
function woocommerce_form_field_type_number( $field, $key, $args, $value ) {
|
||||
/*
|
||||
$args['input_class'] = array();
|
||||
$args['maxlength'] = '';
|
||||
$custom_attributes = array();
|
||||
$field = '<input type="number" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" '.$args['maxlength'].' value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
|
||||
return $field;
|
||||
*/
|
||||
if ( isset( $args['custom_attributes']['display'] ) && 'number' === $args['custom_attributes']['display'] ) {
|
||||
$field = str_replace( '<input type="text" ', '<input type="number" ', $field );
|
||||
}
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_fields_to_store_exporter_order.
|
||||
*
|
||||
* @version 2.3.0
|
||||
* @since 2.2.7
|
||||
*/
|
||||
function add_custom_fields_to_store_exporter_order( $order, $order_id ) {
|
||||
$post_meta = get_post_meta( $order_id );
|
||||
foreach( $post_meta as $key => $values ) {
|
||||
if ( false !== strpos( $key, 'wcj_checkout_field_' ) && isset( $values[0] ) ) {
|
||||
if ( false !== strpos( $key, '_label_' ) ) {
|
||||
continue;
|
||||
}
|
||||
$order->$key = isset( $values[0]['value'] ) ? $values[0]['value'] : $values[0];
|
||||
}
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_fields_to_store_exporter.
|
||||
*/
|
||||
function add_custom_fields_to_store_exporter( $fields ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
|
||||
$the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
|
||||
$the_key = 'wcj_checkout_field_' . $i;
|
||||
$fields[] = array(
|
||||
'name' => $the_section . '_' . $the_key,
|
||||
'label' => get_option( 'wcj_checkout_custom_field_label_' . $i ),
|
||||
);
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_shipping_fields_to_formatted_address.
|
||||
*/
|
||||
/* function add_custom_shipping_fields_to_formatted_address( $fields, $order ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
|
||||
//if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
|
||||
$the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
|
||||
if ( 'shipping' === $the_section ) {
|
||||
$option_name = $the_section . '_' . 'wcj_checkout_field_' . $i;
|
||||
$fields[ $option_name ] = get_post_meta( wcj_get_order_id( $order ), '_' . $option_name, true );
|
||||
}
|
||||
//}
|
||||
}
|
||||
return $fields;
|
||||
} */
|
||||
|
||||
/**
|
||||
* update_custom_checkout_fields_order_meta.
|
||||
*
|
||||
* @version 2.4.7
|
||||
*/
|
||||
function update_custom_checkout_fields_order_meta( $order_id ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
|
||||
$the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
|
||||
$the_type = get_option( 'wcj_checkout_custom_field_type_' . $i );
|
||||
$option_name = $the_section . '_' . 'wcj_checkout_field_' . $i;
|
||||
$option_name_label = $the_section . '_' . 'wcj_checkout_field_label_' . $i;
|
||||
$option_name_type = $the_section . '_' . 'wcj_checkout_field_type_' . $i;
|
||||
if ( ! empty( $_POST[ $option_name ] ) || 'checkbox' === $the_type ) {
|
||||
update_post_meta( $order_id, '_' . $option_name_type, $the_type );
|
||||
update_post_meta( $order_id, '_' . $option_name_label, get_option( 'wcj_checkout_custom_field_label_' . $i ) );
|
||||
if ( 'checkbox' === $the_type ) {
|
||||
$the_value = ( isset( $_POST[ $option_name ] ) ) ? 1 : 0;
|
||||
update_post_meta( $order_id, '_' . $option_name, $the_value );
|
||||
$option_name_checkbox_value = $the_section . '_' . 'wcj_checkout_field_checkbox_value_' . $i;
|
||||
$checkbox_value = ( 1 == $the_value ) ?
|
||||
get_option( 'wcj_checkout_custom_field_checkbox_yes_' . $i ) :
|
||||
get_option( 'wcj_checkout_custom_field_checkbox_no_' . $i );
|
||||
update_post_meta( $order_id, '_' . $option_name_checkbox_value, $checkbox_value );
|
||||
} elseif ( 'radio' === $the_type || 'select' === $the_type ) {
|
||||
update_post_meta( $order_id, '_' . $option_name, wc_clean( $_POST[ $option_name ] ) );
|
||||
$option_name_values = $the_section . '_' . 'wcj_checkout_field_select_options_' . $i;
|
||||
$the_values = get_option( 'wcj_checkout_custom_field_select_options_' . $i );
|
||||
update_post_meta( $order_id, '_' . $option_name_values, $the_values );
|
||||
} else {
|
||||
update_post_meta( $order_id, '_' . $option_name, wc_clean( $_POST[ $option_name ] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_fields_to_emails.
|
||||
*
|
||||
* @version 3.2.2
|
||||
*/
|
||||
function add_custom_fields_to_emails( $order, $sent_to_admin ) {
|
||||
if (
|
||||
( $sent_to_admin && 'yes' === get_option( 'wcj_checkout_custom_fields_email_all_to_admin' ) ) ||
|
||||
( ! $sent_to_admin && 'yes' === get_option( 'wcj_checkout_custom_fields_email_all_to_customer' ) )
|
||||
) {
|
||||
$templates = array(
|
||||
'before' => get_option( 'wcj_checkout_custom_fields_emails_template_before', '' ),
|
||||
'field' => get_option( 'wcj_checkout_custom_fields_emails_template_field', '<p><strong>%label%:</strong> %value%</p>' ),
|
||||
'after' => get_option( 'wcj_checkout_custom_fields_emails_template_after', '' ),
|
||||
);
|
||||
$this->add_custom_fields_to_order_display( $order, '', $templates );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_fields_to_view_order_and_thankyou_pages.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 3.2.2
|
||||
*/
|
||||
function add_custom_fields_to_view_order_and_thankyou_pages( $order ) {
|
||||
$templates = array(
|
||||
'before' => get_option( 'wcj_checkout_custom_fields_order_received_template_before', '' ),
|
||||
'field' => get_option( 'wcj_checkout_custom_fields_order_received_template_field', '<p><strong>%label%:</strong> %value%</p>' ),
|
||||
'after' => get_option( 'wcj_checkout_custom_fields_order_received_template_after', '' ),
|
||||
);
|
||||
$this->add_custom_fields_to_order_display( $order, '', $templates );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_fields_to_order_display.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.3.0
|
||||
* @todo convert from before version 2.3.0
|
||||
*/
|
||||
function add_custom_fields_to_order_display( $order, $section = '', $templates ) {
|
||||
$post_meta = get_post_meta( wcj_get_order_id( $order ) );
|
||||
$final_output = '';
|
||||
foreach( $post_meta as $key => $values ) {
|
||||
if ( false !== strpos( $key, 'wcj_checkout_field_' ) && isset( $values[0] ) ) {
|
||||
// Checking section (if set)
|
||||
if ( '' != $section ) {
|
||||
$the_section = strtok( $key, '_' );
|
||||
if ( $section !== $the_section ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Skipping unnecessary meta
|
||||
if (
|
||||
false !== strpos( $key, '_label_' ) ||
|
||||
false !== strpos( $key, '_type_' ) ||
|
||||
false !== strpos( $key, '_checkbox_value_' ) ||
|
||||
false !== strpos( $key, '_select_options_' )
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
// Field label
|
||||
$label = '';
|
||||
$the_label_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_label_', $key );
|
||||
if ( isset( $post_meta[ $the_label_key ][0] ) ) {
|
||||
$label = $post_meta[ $the_label_key ][0];
|
||||
} elseif ( is_array( $values[0] ) && isset( $values[0]['label'] ) ) {
|
||||
$label = $values[0]['label'];
|
||||
}
|
||||
// Field value
|
||||
$value = '';
|
||||
$_value = ( is_array( $values[0] ) && isset( $values[0]['value'] ) ? $values[0]['value'] : $values[0] );
|
||||
$type_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_type_', $key );
|
||||
if ( isset( $post_meta[ $type_key ][0] ) && 'checkbox' === $post_meta[ $type_key ][0] ) {
|
||||
$checkbox_value_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_checkbox_value_', $key );
|
||||
$value = ( isset( $post_meta[ $checkbox_value_key ][0] ) ? $post_meta[ $checkbox_value_key ][0] : $_value );
|
||||
} elseif ( isset( $post_meta[ $type_key ][0] ) && ( 'radio' === $post_meta[ $type_key ][0] || 'select' === $post_meta[ $type_key ][0] ) ) {
|
||||
$select_values_key = str_replace( 'wcj_checkout_field_', 'wcj_checkout_field_select_options_', $key );
|
||||
$select_values = ( isset( $post_meta[ $select_values_key ][0] ) ) ? $post_meta[ $select_values_key ][0] : '';
|
||||
if ( ! empty( $select_values ) ) {
|
||||
$select_values_prepared = wcj_get_select_options( $select_values );
|
||||
$value = ( isset( $select_values_prepared[ $_value ] ) ? $select_values_prepared[ $_value ] : $_value );
|
||||
} else {
|
||||
$value = $_value;
|
||||
}
|
||||
} else {
|
||||
$value = $_value;
|
||||
}
|
||||
// Adding field to final output
|
||||
if ( '' != $label || '' != $value ) {
|
||||
$replaced_values = array(
|
||||
'%label%' => $label,
|
||||
'%value%' => $value,
|
||||
);
|
||||
$final_output .= str_replace( array_keys( $replaced_values ), $replaced_values, $templates['field'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
// Outputting
|
||||
if ( '' != $final_output ) {
|
||||
echo $templates['before'] . $final_output . $templates['after'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_woocommerce_admin_fields.
|
||||
*
|
||||
* @version 2.4.7
|
||||
* @todo Converting from before version 2.3.0: section?
|
||||
*/
|
||||
function add_woocommerce_admin_fields( $fields, $section ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
|
||||
$the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
|
||||
if ( $section != $the_section ) {
|
||||
continue;
|
||||
}
|
||||
$the_type = get_option( 'wcj_checkout_custom_field_type_' . $i );
|
||||
if ( 'select' === $the_type ) {
|
||||
$the_class = 'first';
|
||||
$options = wcj_get_select_options( get_option( 'wcj_checkout_custom_field_select_options_' . $i ) );
|
||||
} elseif ( 'radio' === $the_type ) {
|
||||
$the_options = get_post_meta( get_the_ID(), '_' . $section . '_' . 'wcj_checkout_field_select_options_' . $i, true );
|
||||
if ( ! empty( $the_options ) ) {
|
||||
$the_type = 'select';
|
||||
$the_class = 'first';
|
||||
$options = wcj_get_select_options( $the_options );
|
||||
} else {
|
||||
$the_options = wcj_get_select_options( get_option( 'wcj_checkout_custom_field_select_options_' . $i ) );
|
||||
if ( ! empty( $the_options ) ) {
|
||||
$the_type = 'select';
|
||||
$the_class = 'first';
|
||||
$options = $the_options;
|
||||
} else {
|
||||
$the_type = 'text';
|
||||
$the_class = 'short';
|
||||
}
|
||||
}
|
||||
} elseif ( 'country' === $the_type ) {
|
||||
$the_type = 'select';
|
||||
$the_class = 'js_field-country select short';
|
||||
$options = WC()->countries->get_allowed_countries();
|
||||
} else {
|
||||
$the_type = 'text';
|
||||
$the_class = 'short';
|
||||
}
|
||||
$the_key = 'wcj_checkout_field_' . $i;
|
||||
$the_key_label = 'wcj_checkout_field_label_' . $i;
|
||||
$the_meta = get_post_meta( get_the_ID(), '_' . $section . '_' . $the_key, true );
|
||||
if ( is_array( $the_meta ) ) {
|
||||
// Converting from before version 2.3.0
|
||||
if ( isset( $the_meta['value'] ) ) update_post_meta( get_the_ID(), '_' . $section . '_' . $the_key, $the_meta['value'] );
|
||||
if ( isset( $the_meta['label'] ) ) update_post_meta( get_the_ID(), '_' . $section . '_' . $the_key_label, $the_meta['label'] );
|
||||
}
|
||||
$fields[ $the_key ] = array(
|
||||
'type' => $the_type,
|
||||
'label' => ( '' != get_post_meta( get_the_ID(), '_' . $section . '_' . $the_key_label, true ) ) ?
|
||||
get_post_meta( get_the_ID(), '_' . $section . '_' . $the_key_label, true ) :
|
||||
get_option( 'wcj_checkout_custom_field_label_' . $i ),
|
||||
'show' => true,
|
||||
'class' => $the_class,
|
||||
'wrapper_class' => 'form-field-wide',
|
||||
);
|
||||
if ( isset( $options ) ) {
|
||||
$fields[ $the_key ]['options'] = $options;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_billing_fields_to_admin_order_display.
|
||||
*/
|
||||
function add_custom_billing_fields_to_admin_order_display( $fields ) {
|
||||
return $this->add_woocommerce_admin_fields( $fields, 'billing' );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_shipping_fields_to_admin_order_display.
|
||||
*/
|
||||
function add_custom_shipping_fields_to_admin_order_display( $fields ) {
|
||||
return $this->add_woocommerce_admin_fields( $fields, 'shipping' );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_order_and_account_fields_to_admin_order_display
|
||||
*
|
||||
* @version 3.2.2
|
||||
*/
|
||||
function add_custom_order_and_account_fields_to_admin_order_display( $order ) {
|
||||
$templates = array(
|
||||
'before' => '<div class="clear"></div><p>',
|
||||
'field' => '<strong>%label%: </strong>%value%<br>',
|
||||
'after' => '</p>',
|
||||
);
|
||||
$this->add_custom_fields_to_order_display( $order, 'order', $templates );
|
||||
$this->add_custom_fields_to_order_display( $order, 'account', $templates );
|
||||
/*
|
||||
$fields = $this->add_woocommerce_admin_fields( $fields, 'order' );
|
||||
$fields = $this->add_woocommerce_admin_fields( $fields, 'account' );
|
||||
return $fields;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* is_visible.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.6.0
|
||||
* @todo add "user roles to include/exclude"
|
||||
*/
|
||||
function is_visible( $i ) {
|
||||
|
||||
if ( apply_filters( 'wcj_checkout_custom_field_always_visible_on_empty_cart', false ) && WC()->cart->is_empty() ) {
|
||||
// Added for "One Page Checkout" plugin compatibility.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Checking categories
|
||||
$categories_ex = get_option( 'wcj_checkout_custom_field_categories_ex_' . $i );
|
||||
if ( ! empty( $categories_ex ) ) {
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
$product_categories = get_the_terms( $values['product_id'], 'product_cat' );
|
||||
if ( empty( $product_categories ) ) {
|
||||
continue;
|
||||
}
|
||||
foreach( $product_categories as $product_category ) {
|
||||
if ( in_array( $product_category->term_id, $categories_ex ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$categories_in = get_option( 'wcj_checkout_custom_field_categories_in_' . $i );
|
||||
if ( ! empty( $categories_in ) ) {
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
$product_categories = get_the_terms( $values['product_id'], 'product_cat' );
|
||||
if ( empty( $product_categories ) ) {
|
||||
continue;
|
||||
}
|
||||
foreach( $product_categories as $product_category ) {
|
||||
if ( in_array( $product_category->term_id, $categories_in ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checking products
|
||||
$products_ex = get_option( 'wcj_checkout_custom_field_products_ex_' . $i );
|
||||
if ( ! empty( $products_ex ) ) {
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
if ( in_array( $values['product_id'], $products_ex ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
$products_in = get_option( 'wcj_checkout_custom_field_products_in_' . $i );
|
||||
if ( ! empty( $products_in ) ) {
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
if ( in_array( $values['product_id'], $products_in ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checking min/max cart amount
|
||||
$cart_total = false;
|
||||
if ( ( $min_cart_amount = get_option( 'wcj_checkout_custom_field_min_cart_amount_' . $i, 0 ) ) > 0 ) {
|
||||
WC()->cart->calculate_totals();
|
||||
$cart_total = WC()->cart->total;
|
||||
if ( $cart_total < $min_cart_amount ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( ( $max_cart_amount = get_option( 'wcj_checkout_custom_field_max_cart_amount_' . $i, 0 ) ) > 0 ) {
|
||||
if ( false === $cart_total ) {
|
||||
WC()->cart->calculate_totals();
|
||||
$cart_total = WC()->cart->total;
|
||||
}
|
||||
if ( $cart_total > $max_cart_amount ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// All passed
|
||||
return apply_filters( 'wcj_checkout_custom_field_visible', true, $i );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_checkout_fields.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @todo (maybe) fix - priority seems to not affect tab order (same in Checkout Core Fields module)
|
||||
*/
|
||||
function add_custom_checkout_fields( $fields ) {
|
||||
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_fields_total_number', 1 ) ); $i++ ) {
|
||||
|
||||
if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i ) ) {
|
||||
|
||||
if ( ! $this->is_visible( $i ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$the_type = get_option( 'wcj_checkout_custom_field_type_' . $i );
|
||||
$custom_attributes = array();
|
||||
if ( 'datepicker' === $the_type || 'weekpicker' === $the_type || 'timepicker' === $the_type || 'number' === $the_type ) {
|
||||
if ( 'datepicker' === $the_type || 'weekpicker' === $the_type ) {
|
||||
$datepicker_format_option = get_option( 'wcj_checkout_custom_field_datepicker_format_' . $i, '' );
|
||||
$datepicker_format = ( '' == $datepicker_format_option ) ? get_option( 'date_format' ) : $datepicker_format_option;
|
||||
$datepicker_format = wcj_date_format_php_to_js( $datepicker_format );
|
||||
$custom_attributes['dateformat'] = $datepicker_format;
|
||||
$custom_attributes['mindate'] = get_option( 'wcj_checkout_custom_field_datepicker_mindate_' . $i, -365 );
|
||||
if ( 0 == $custom_attributes['mindate'] ) {
|
||||
$custom_attributes['mindate'] = 'zero';
|
||||
}
|
||||
$custom_attributes['maxdate'] = get_option( 'wcj_checkout_custom_field_datepicker_maxdate_' . $i, 365 );
|
||||
if ( 0 == $custom_attributes['maxdate'] ) {
|
||||
$custom_attributes['maxdate'] = 'zero';
|
||||
}
|
||||
$custom_attributes['firstday'] = get_option( 'wcj_checkout_custom_field_datepicker_firstday_' . $i, 0 );
|
||||
if ( 'yes' === get_option( 'wcj_checkout_custom_field_datepicker_changeyear_' . $i, 'yes' ) ) {
|
||||
$custom_attributes['changeyear'] = 1;
|
||||
$custom_attributes['yearrange'] = get_option( 'wcj_checkout_custom_field_datepicker_yearrange_' . $i, 'c-10:c+10' );
|
||||
}
|
||||
$custom_attributes['display'] = ( 'datepicker' === $the_type ) ? 'date' : 'week';
|
||||
} elseif ( 'timepicker' === $the_type ) {
|
||||
$custom_attributes['timeformat'] = get_option( 'wcj_checkout_custom_field_timepicker_format_' . $i, 'hh:mm p' );
|
||||
$custom_attributes['interval'] = get_option( 'wcj_checkout_custom_field_timepicker_interval_' . $i, 15 );
|
||||
$custom_attributes['display'] = 'time';
|
||||
} else/* if ( 'number' === $the_type ) */ {
|
||||
$custom_attributes['display'] = $the_type;
|
||||
}
|
||||
$the_type = 'text';
|
||||
}
|
||||
$the_section = get_option( 'wcj_checkout_custom_field_section_' . $i );
|
||||
$the_key = 'wcj_checkout_field_' . $i;
|
||||
|
||||
$the_field = array(
|
||||
'type' => $the_type,
|
||||
'label' => get_option( 'wcj_checkout_custom_field_label_' . $i ),
|
||||
'placeholder' => get_option( 'wcj_checkout_custom_field_placeholder_' . $i ),
|
||||
'required' => ( 'yes' === get_option( 'wcj_checkout_custom_field_required_' . $i ) ) ? true : false,
|
||||
'custom_attributes' => $custom_attributes,
|
||||
'clear' => ( 'yes' === get_option( 'wcj_checkout_custom_field_clear_' . $i ) ) ? true : false,
|
||||
'class' => array( get_option( 'wcj_checkout_custom_field_class_' . $i ), ),
|
||||
'priority' => get_option( 'wcj_checkout_custom_field_priority_' . $i, '' ),
|
||||
);
|
||||
|
||||
if ( 'select' === $the_type || 'radio' === $the_type ) {
|
||||
$select_options_raw = get_option( 'wcj_checkout_custom_field_select_options_' . $i );
|
||||
$select_options = wcj_get_select_options( $select_options_raw );
|
||||
if ( 'select' === $the_type ) {
|
||||
$placeholder = get_option( 'wcj_checkout_custom_field_placeholder_' . $i );
|
||||
if ( '' != $placeholder ) {
|
||||
$select_options = array_replace( array( '' => $placeholder ), $select_options );
|
||||
}
|
||||
}
|
||||
$the_field['options'] = $select_options;
|
||||
if ( ! empty( $select_options ) ) {
|
||||
reset( $select_options );
|
||||
$the_field['default'] = key( $select_options );
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'checkbox' === $the_type ) {
|
||||
$the_field['default'] = ( 'yes' === get_option( 'wcj_checkout_custom_field_checkbox_default_' . $i ) ) ? 1 : 0;
|
||||
}
|
||||
|
||||
$fields[ $the_section ][ $the_section . '_' . $the_key ] = $the_field;
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Checkout_Custom_Fields();
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Checkout Custom Info
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Checkout_Custom_Info' ) ) :
|
||||
|
||||
class WCJ_Checkout_Custom_Info extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'checkout_custom_info';
|
||||
$this->short_desc = __( 'Checkout Custom Info', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add custom info to the checkout page.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-checkout-custom-info';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_info_total_number', 1 ) ); $i++) {
|
||||
add_action(
|
||||
get_option( 'wcj_checkout_custom_info_hook_' . $i, 'woocommerce_checkout_after_order_review' ),
|
||||
array( $this, 'add_checkout_custom_info' ),
|
||||
get_option( 'wcj_checkout_custom_info_priority_' . $i, 10 )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_checkout_custom_info.
|
||||
*
|
||||
* @version 2.4.7
|
||||
*/
|
||||
function add_checkout_custom_info() {
|
||||
$current_filter = current_filter();
|
||||
$current_filter_priority = wcj_current_filter_priority();
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_custom_info_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if (
|
||||
'' != get_option( 'wcj_checkout_custom_info_content_' . $i ) &&
|
||||
$current_filter === get_option( 'wcj_checkout_custom_info_hook_' . $i ) &&
|
||||
$current_filter_priority == get_option( 'wcj_checkout_custom_info_priority_' . $i, 10 )
|
||||
) {
|
||||
echo do_shortcode( get_option( 'wcj_checkout_custom_info_content_' . $i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Checkout_Custom_Info();
|
||||
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Checkout Customization
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.7.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Checkout_Customization' ) ) :
|
||||
|
||||
class WCJ_Checkout_Customization extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'checkout_customization';
|
||||
$this->short_desc = __( 'Checkout Customization', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Customize WooCommerce checkout - restrict countries by customer\'s IP; hide "Order Again" button; disable selected fields on checkout for logged users and more.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-checkout-customization';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// "Create an account?" Checkbox
|
||||
if ( 'default' != ( $create_account_default = get_option( 'wcj_checkout_create_account_default_checked', 'default' ) ) ) {
|
||||
if ( 'checked' === $create_account_default ) {
|
||||
add_filter( 'woocommerce_create_account_default_checked', '__return_true' );
|
||||
} elseif ( 'not_checked' === $create_account_default ) {
|
||||
add_filter( 'woocommerce_create_account_default_checked', '__return_false' );
|
||||
}
|
||||
}
|
||||
// Hide "Order Again" button
|
||||
if ( 'yes' === get_option( 'wcj_checkout_hide_order_again', 'no' ) ) {
|
||||
add_action( 'init', array( $this, 'checkout_hide_order_again' ), PHP_INT_MAX );
|
||||
}
|
||||
// Disable Fields on Checkout for Logged Users
|
||||
add_filter( 'woocommerce_checkout_fields' , array( $this, 'maybe_disable_fields' ), PHP_INT_MAX );
|
||||
$checkout_fields_types = array(
|
||||
'country',
|
||||
'state',
|
||||
'textarea',
|
||||
'checkbox',
|
||||
'password',
|
||||
'text',
|
||||
'email',
|
||||
'tel',
|
||||
'number',
|
||||
'select',
|
||||
'radio',
|
||||
);
|
||||
foreach ( $checkout_fields_types as $checkout_fields_type ) {
|
||||
add_filter( 'woocommerce_form_field_' . $checkout_fields_type, array( $this, 'maybe_add_description' ), PHP_INT_MAX, 4 );
|
||||
}
|
||||
// Custom "order received" message text
|
||||
if ( 'yes' === get_option( 'wcj_checkout_customization_order_received_message_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_thankyou_order_received_text', array( $this, 'customize_order_received_message' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
// Custom checkout login message
|
||||
if ( 'yes' === get_option( 'wcj_checkout_customization_checkout_login_message_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_checkout_login_message', array( $this, 'checkout_login_message' ), PHP_INT_MAX );
|
||||
}
|
||||
// Restrict countries by customer's IP
|
||||
if ( 'yes' === get_option( 'wcj_checkout_restrict_countries_by_customer_ip_billing', 'no' ) ) {
|
||||
add_filter( 'woocommerce_countries_allowed_countries', array( $this, 'restrict_countries_by_customer_ip' ), PHP_INT_MAX );
|
||||
}
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_checkout_restrict_countries_by_customer_ip_shipping', 'no' ) ) ) {
|
||||
add_filter( 'woocommerce_countries_shipping_countries', array( $this, 'restrict_countries_by_customer_ip' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* restrict_countries_by_customer_ip.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
* @todo (maybe) handle case when `wcj_get_country_by_ip()` returns empty string
|
||||
* @todo (maybe) for shipping countries - filter `woocommerce_ship_to_countries` option
|
||||
*/
|
||||
function restrict_countries_by_customer_ip( $countries ) {
|
||||
$user_country = wcj_get_country_by_ip();
|
||||
return array( $user_country => wcj_get_country_name_by_code( $user_country ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* checkout_login_message.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function checkout_login_message( $message ) {
|
||||
return get_option( 'wcj_checkout_customization_checkout_login_message', __( 'Returning customer?', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* customize_order_received_message.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function customize_order_received_message( $message, $_order ) {
|
||||
if ( null != $_order ) {
|
||||
global $post;
|
||||
$post = get_post( wcj_get_order_id( $_order ) );
|
||||
setup_postdata( $post );
|
||||
}
|
||||
$message = do_shortcode( get_option( 'wcj_checkout_customization_order_received_message', __( 'Thank you. Your order has been received.', 'woocommerce' ) ) );
|
||||
if ( null != $_order ) {
|
||||
wp_reset_postdata();
|
||||
}
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_description.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function maybe_add_description( $field, $key, $args, $value ) {
|
||||
if ( is_user_logged_in() ) {
|
||||
$fields_to_disable = get_option( 'wcj_checkout_customization_disable_fields_for_logged', '' );
|
||||
$fields_to_disable_custom_r = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_r', '' ) ) ) );
|
||||
$fields_to_disable_custom_d = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_d', '' ) ) ) );
|
||||
$fields_to_disable = array_merge( $fields_to_disable, $fields_to_disable_custom_r, $fields_to_disable_custom_d );
|
||||
if ( ! empty( $fields_to_disable ) ) {
|
||||
if ( in_array( $key, $fields_to_disable ) ) {
|
||||
$desc = get_option( 'wcj_checkout_customization_disable_fields_for_logged_message',
|
||||
'<em>' . __( 'This field can not be changed', 'woocommerce-jetpack' ) . '</em>' );
|
||||
if ( '' != $desc ) {
|
||||
$field = str_replace( '__WCJ_TEMPORARY_VALUE_TO_REPLACE__', $desc, $field );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_disable_fields.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.9.0
|
||||
* @see woocommerce_form_field
|
||||
* @todo (maybe) add single option (probably checkbox) to disable all fields
|
||||
* @todo (maybe) on `'billing_country', 'shipping_country'` change to simple `select` (i.e. probably remove `wc-enhanced-select` class)
|
||||
*/
|
||||
function maybe_disable_fields( $checkout_fields ) {
|
||||
if ( is_user_logged_in() ) {
|
||||
$fields_to_disable = get_option( 'wcj_checkout_customization_disable_fields_for_logged', '' );
|
||||
$fields_to_disable_custom_r = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_r', '' ) ) ) );
|
||||
$fields_to_disable_custom_d = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_d', '' ) ) ) );
|
||||
$fields_to_disable = array_merge( $fields_to_disable, $fields_to_disable_custom_r, $fields_to_disable_custom_d );
|
||||
$disable_type_fields = array_merge( array( 'billing_country', 'shipping_country' ), $fields_to_disable_custom_d );
|
||||
$do_add_desc_placeholder = ( '' != get_option( 'wcj_checkout_customization_disable_fields_for_logged_message',
|
||||
'<em>' . __( 'This field can not be changed', 'woocommerce-jetpack' ) . '</em>' ) );
|
||||
if ( ! empty( $fields_to_disable ) ) {
|
||||
foreach ( $fields_to_disable as $field_to_disable ) {
|
||||
$section = explode( '_', $field_to_disable );
|
||||
$section = $section[0];
|
||||
if ( isset( $checkout_fields[ $section ][ $field_to_disable ] ) ) {
|
||||
if ( ! isset( $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] ) ) {
|
||||
$checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] = array();
|
||||
}
|
||||
$custom_attributes = ( in_array( $field_to_disable, $disable_type_fields ) ? array( 'disabled' => 'disabled' ) : array( 'readonly' => 'readonly' ) );
|
||||
$checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] = array_merge(
|
||||
$checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'],
|
||||
$custom_attributes
|
||||
);
|
||||
if ( $do_add_desc_placeholder ) {
|
||||
$checkout_fields[ $section ][ $field_to_disable ]['description'] = '__WCJ_TEMPORARY_VALUE_TO_REPLACE__';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $checkout_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* checkout_hide_order_again.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function checkout_hide_order_again() {
|
||||
remove_action( 'woocommerce_order_details_after_order_table', 'woocommerce_order_again_button' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Checkout_Customization();
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Checkout Fees
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.7.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Checkout_Fees' ) ) :
|
||||
|
||||
class WCJ_Checkout_Fees extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.7.0
|
||||
* @todo (maybe) rename module to "Cart & Checkout Fees"
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'checkout_fees';
|
||||
$this->short_desc = __( 'Checkout Fees', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add fees to WooCommerce cart & checkout.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-checkout-fees';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'woocommerce_cart_calculate_fees', array( $this, 'add_fees' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_fees.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.7.0
|
||||
* @todo fees with same title
|
||||
* @todo options: `tax_class`
|
||||
* @todo options: `cart total` (for percent) - include/exclude shipping etc. - https://docs.woocommerce.com/wc-apidocs/class-WC_Cart.html
|
||||
* @todo options: `rounding` (for percent)
|
||||
* @todo options: `min/max cart amount`
|
||||
* @todo options: `products, cats, tags to include/exclude`
|
||||
* @todo options: `countries to include/exclude`
|
||||
* @todo options: `user roles to include/exclude`
|
||||
* @todo see https://wcbooster.zendesk.com/agent/tickets/446
|
||||
*/
|
||||
function add_fees( $cart ) {
|
||||
if ( ! wcj_is_frontend() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$enabled = get_option( 'wcj_checkout_fees_data_enabled', array() );
|
||||
$titles = get_option( 'wcj_checkout_fees_data_titles', array() );
|
||||
$types = get_option( 'wcj_checkout_fees_data_types', array() );
|
||||
$values = get_option( 'wcj_checkout_fees_data_values', array() );
|
||||
$taxable = get_option( 'wcj_checkout_fees_data_taxable', array() );
|
||||
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_fees_total_number', 1 ) );
|
||||
$fees_to_add = array();
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if (
|
||||
( isset( $enabled[ $i ] ) && 'no' === $enabled[ $i ] ) ||
|
||||
( 0 == ( $value = ( isset( $values[ $i ] ) ? $values[ $i ] : 0 ) ) )
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
$title = ( isset( $titles[ $i ] ) ? $titles[ $i ] : __( 'Fee', 'woocommerce-jetpack' ) . ' #' . $i );
|
||||
if ( isset( $types[ $i ] ) && 'percent' === $types[ $i ] ) {
|
||||
$value = $cart->get_cart_contents_total() * $value / 100;
|
||||
}
|
||||
$fees_to_add[ $title ] = array(
|
||||
'name' => $title,
|
||||
'amount' => $value,
|
||||
'taxable' => ( isset( $taxable[ $i ] ) ? ( 'yes' === $taxable[ $i ] ) : true ),
|
||||
'tax_class' => 'standard',
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $fees_to_add ) ) {
|
||||
foreach ( $fees_to_add as $fee_to_add ) {
|
||||
$cart->add_fee( $fee_to_add['name'], $fee_to_add['amount'], $fee_to_add['taxable'], $fee_to_add['tax_class'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Checkout_Fees();
|
||||
@@ -0,0 +1,716 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Checkout Files Upload
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.4.5
|
||||
* @author Algoritmika Ltd.
|
||||
* @todo styling options
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Checkout_Files_Upload' ) ) :
|
||||
|
||||
class WCJ_Checkout_Files_Upload extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.4.5
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'checkout_files_upload';
|
||||
$this->short_desc = __( 'Checkout Files Upload', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Let customers upload files on (or after) the checkout.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-checkout-files-upload';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_file_admin_order_meta_box' ) );
|
||||
add_action( 'init', array( $this, 'process_checkout_files_upload' ) );
|
||||
if ( 'yes' === get_option( 'wcj_checkout_files_upload_remove_on_empty_cart', 'no' ) ) {
|
||||
add_action( 'woocommerce_cart_item_removed', array( $this, 'remove_files_on_empty_cart' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( 'disable' != ( $the_hook = get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' ) ) ) {
|
||||
add_action( $the_hook, array( $this, 'add_files_upload_form_to_checkout_frontend' ), get_option( 'wcj_checkout_files_upload_hook_priority_' . $i, 10 ) );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_thankyou_' . $i, 'no' ) ) {
|
||||
add_action( 'woocommerce_thankyou', array( $this, 'add_files_upload_form_to_thankyou_and_myaccount_page' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_myaccount_' . $i, 'no' ) ) {
|
||||
add_action( 'woocommerce_view_order', array( $this, 'add_files_upload_form_to_thankyou_and_myaccount_page' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
}
|
||||
add_action( 'woocommerce_checkout_order_processed', array( $this, 'add_files_to_order' ), PHP_INT_MAX, 2 );
|
||||
add_action( 'woocommerce_after_checkout_validation', array( $this, 'validate_on_checkout' ) );
|
||||
add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_files_to_order_display' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_email_after_order_table', array( $this, 'add_files_to_order_display' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_email_attachments', array( $this, 'add_files_to_email_attachments' ), PHP_INT_MAX, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_files_to_email_attachments.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.5
|
||||
*/
|
||||
function add_files_to_email_attachments( $attachments, $status, $order ) {
|
||||
if (
|
||||
( 'new_order' === $status && 'yes' === get_option( 'wcj_checkout_files_upload_attach_to_admin_new_order', 'yes' ) ) ||
|
||||
( 'customer_processing_order' === $status && 'yes' === get_option( 'wcj_checkout_files_upload_attach_to_customer_processing_order', 'yes' ) )
|
||||
) {
|
||||
$total_files = get_post_meta( wcj_get_order_id( $order ), '_' . 'wcj_checkout_files_total_files', true );
|
||||
for ( $i = 1; $i <= $total_files; $i++ ) {
|
||||
$attachments[] = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . get_post_meta( wcj_get_order_id( $order ), '_' . 'wcj_checkout_files_upload_' . $i, true );
|
||||
}
|
||||
}
|
||||
return $attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_files_to_order_display.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.4.7
|
||||
*/
|
||||
function add_files_to_order_display( $order ) {
|
||||
$order_id = wcj_get_order_id( $order );
|
||||
$html = '';
|
||||
$total_files = get_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', true );
|
||||
for ( $i = 1; $i <= $total_files; $i++ ) {
|
||||
$real_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
|
||||
if ( '' != $real_file_name ) {
|
||||
$html .= __( 'File', 'woocommerce-jetpack' ) . ': ' . $real_file_name . '<br>';
|
||||
}
|
||||
}
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* validate_on_checkout.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.4.5
|
||||
*/
|
||||
function validate_on_checkout( $posted ) {
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if (
|
||||
'yes' === get_option( 'wcj_checkout_files_upload_enabled_' . $i, 'yes' ) &&
|
||||
$this->is_visible( $i ) &&
|
||||
'disable' != get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' )
|
||||
) {
|
||||
if ( 'yes' === get_option( 'wcj_checkout_files_upload_required_' . $i, 'no' ) && null === wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) {
|
||||
// Is required
|
||||
wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_required_' . $i, __( 'File is required!', 'woocommerce-jetpack' ) ), 'error' );
|
||||
}
|
||||
if ( null === wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) {
|
||||
continue;
|
||||
}
|
||||
$file_name = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
|
||||
$file_name = $file_name['name'];
|
||||
$file_type = '.' . pathinfo( $file_name, PATHINFO_EXTENSION );
|
||||
if ( '' != ( $file_accept = get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) ) ) {
|
||||
// Validate file type
|
||||
$file_accept = explode( ',', $file_accept );
|
||||
if ( is_array( $file_accept ) && ! empty( $file_accept ) ) {
|
||||
if ( ! in_array( $file_type, $file_accept ) ) {
|
||||
wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
|
||||
__( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $file_name ), 'error' );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $this->is_extension_blocked( $file_type ) ) {
|
||||
wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
|
||||
__( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $file_name ), 'error' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_file_admin_order_meta_box.
|
||||
*
|
||||
* @version 2.4.5
|
||||
* @since 2.4.5
|
||||
*/
|
||||
function add_file_admin_order_meta_box() {
|
||||
$screen = 'shop_order';
|
||||
$context = 'side';
|
||||
$priority = 'high';
|
||||
add_meta_box(
|
||||
'wc-jetpack-' . $this->id,
|
||||
__( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Uploaded Files', 'woocommerce-jetpack' ),
|
||||
array( $this, 'create_file_admin_order_meta_box' ),
|
||||
$screen,
|
||||
$context,
|
||||
$priority
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_file_admin_order_meta_box.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.4.5
|
||||
*/
|
||||
function create_file_admin_order_meta_box() {
|
||||
$order_id = get_the_ID();
|
||||
$html = '';
|
||||
$total_files = get_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', true );
|
||||
$files_exists = false;
|
||||
for ( $i = 1; $i <= $total_files; $i++ ) {
|
||||
$order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
|
||||
$real_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
|
||||
if ( '' != $order_file_name ) {
|
||||
$files_exists = true;
|
||||
$html .= '<p><a href="' . add_query_arg(
|
||||
array(
|
||||
'wcj_download_checkout_file_admin' => $order_file_name,
|
||||
'wcj_checkout_file_number' => $i,
|
||||
) ) . '">' . $real_file_name . '</a></p>';
|
||||
}
|
||||
}
|
||||
if ( ! $files_exists ) {
|
||||
$html .= '<p><em>' . __( 'No files uploaded.', 'woocommerce-jetpack' ) . '</em></p>';
|
||||
} else {
|
||||
$html .= '<p><a style="color:#a00;" href="' . add_query_arg( 'wcj_download_checkout_file_admin_delete_all', $order_id ) . '"' . wcj_get_js_confirmation() . '>' .
|
||||
__( 'Delete all files', 'woocommerce-jetpack' ) . '</a></p>';
|
||||
}
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_extension_blocked.
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @since 3.2.3
|
||||
*/
|
||||
function is_extension_blocked( $ext ) {
|
||||
if ( 'no' === get_option( 'wcj_checkout_files_upload_block_files_enabled', 'yes' ) ) {
|
||||
return false;
|
||||
}
|
||||
$ext = strtolower( $ext );
|
||||
if ( strlen( $ext ) > 0 && '.' === $ext[0] ) {
|
||||
$ext = substr( $ext, 1 );
|
||||
}
|
||||
$blocked_file_exts = get_option( 'wcj_checkout_files_upload_block_files_exts',
|
||||
'bat|exe|cmd|sh|php|php0|php1|php2|php3|php4|php5|php6|php7|php8|php9|ph|ph0|ph1|ph2|ph3|ph4|ph5|ph6|ph7|ph8|ph9|pl|cgi|386|dll|com|torrent|js|app|jar|pif|vb|vbscript|wsf|asp|cer|csr|jsp|drv|sys|ade|adp|bas|chm|cpl|crt|csh|fxp|hlp|hta|inf|ins|isp|jse|htaccess|htpasswd|ksh|lnk|mdb|mde|mdt|mdw|msc|msi|msp|mst|ops|pcd|prg|reg|scr|sct|shb|shs|url|vbe|vbs|wsc|wsf|wsh|html|htm'
|
||||
);
|
||||
$blocked_file_exts = explode( '|', $blocked_file_exts );
|
||||
return in_array( $ext, $blocked_file_exts );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_files_to_order.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.4.5
|
||||
*/
|
||||
function add_files_to_order( $order_id, $posted ) {
|
||||
$upload_dir = wcj_get_wcj_uploads_dir( 'checkout_files_upload' );
|
||||
if ( ! file_exists( $upload_dir ) ) {
|
||||
mkdir( $upload_dir, 0755, true );
|
||||
}
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( null !== wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) {
|
||||
$session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
|
||||
$file_name = $session_data['name'];
|
||||
$ext = pathinfo( $file_name, PATHINFO_EXTENSION );
|
||||
$download_file_name = $order_id . '_' . $i . '.' . $ext;
|
||||
$file_path = $upload_dir . '/' . $download_file_name;
|
||||
$tmp_file_name = $session_data['tmp_name'];
|
||||
$file_data = file_get_contents( $tmp_file_name );
|
||||
if ( ! $this->is_extension_blocked( $ext ) ) { // should already be validated earlier, but just in case...
|
||||
file_put_contents( $file_path, $file_data );
|
||||
}
|
||||
unlink( $tmp_file_name );
|
||||
wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
|
||||
update_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, $download_file_name );
|
||||
update_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, $file_name );
|
||||
}
|
||||
}
|
||||
update_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', $total_number );
|
||||
}
|
||||
|
||||
/**
|
||||
* remove_files_on_empty_cart.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function remove_files_on_empty_cart( $cart_item_key, $cart ) {
|
||||
if ( $cart->is_empty() ) {
|
||||
wcj_session_maybe_start();
|
||||
$any_files_removed = false;
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) ); $i++ ) {
|
||||
if ( null != ( $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) ) {
|
||||
$any_files_removed = true;
|
||||
if ( isset( $session_data['tmp_name'] ) ) {
|
||||
unlink( $session_data['tmp_name'] );
|
||||
}
|
||||
wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
|
||||
}
|
||||
}
|
||||
if ( $any_files_removed && 'yes' === get_option( 'wcj_checkout_files_upload_remove_on_empty_cart_add_notice', 'no' ) ) {
|
||||
wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_remove_on_empty_cart', __( 'Files were successfully removed.', 'woocommerce-jetpack' ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* process_checkout_files_upload.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.4.5
|
||||
* @todo add option for admin to delete files one by one (i.e. not all at once)
|
||||
*/
|
||||
function process_checkout_files_upload() {
|
||||
wcj_session_maybe_start();
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
|
||||
// Remove file
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( isset( $_POST[ 'wcj_remove_checkout_file_' . $i ] ) ) {
|
||||
if ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ) {
|
||||
$order_id = $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ];
|
||||
$order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
|
||||
if ( '' != $order_file_name ) {
|
||||
$file_path = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name;
|
||||
unlink( $file_path );
|
||||
$file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
|
||||
wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_remove_' . $i,
|
||||
__( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $file_name ) );
|
||||
delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i );
|
||||
delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i );
|
||||
do_action( 'wcj_checkout_files_upload', 'remove_file', $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] );
|
||||
}
|
||||
} else {
|
||||
$session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
|
||||
unlink( $session_data['tmp_name'] );
|
||||
wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_remove_' . $i,
|
||||
__( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $session_data['name'] ) );
|
||||
wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
|
||||
do_action( 'wcj_checkout_files_upload', 'remove_file', false );
|
||||
}
|
||||
}
|
||||
}
|
||||
// Upload file
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( isset( $_POST[ 'wcj_upload_checkout_file_' . $i ] ) ) {
|
||||
$file_name = 'wcj_checkout_files_upload_' . $i;
|
||||
if ( isset( $_FILES[ $file_name ] ) && '' != $_FILES[ $file_name ]['tmp_name'] ) {
|
||||
// Validate
|
||||
$is_valid = true;
|
||||
$real_file_name = $_FILES[ $file_name ]['name'];
|
||||
$file_type = '.' . pathinfo( $real_file_name, PATHINFO_EXTENSION );
|
||||
if ( '' != ( $file_accept = get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) ) ) {
|
||||
// Validate file type
|
||||
$file_accept = explode( ',', $file_accept );
|
||||
if ( is_array( $file_accept ) && ! empty( $file_accept ) ) {
|
||||
if ( ! in_array( $file_type, $file_accept ) ) {
|
||||
wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
|
||||
__( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $real_file_name ), 'error' );
|
||||
$is_valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $this->is_extension_blocked( $file_type ) ) {
|
||||
wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_wrong_file_type_' . $i,
|
||||
__( 'Wrong file type: "%s"!', 'woocommerce-jetpack' ) ), $real_file_name ), 'error' );
|
||||
$is_valid = false;
|
||||
}
|
||||
if ( $is_valid ) {
|
||||
// To session
|
||||
$tmp_dest_file = tempnam( sys_get_temp_dir(), 'wcj' );
|
||||
move_uploaded_file( $_FILES[ $file_name ]['tmp_name'], $tmp_dest_file );
|
||||
$session_data = $_FILES[ $file_name ];
|
||||
$session_data['tmp_name'] = $tmp_dest_file;
|
||||
wcj_session_set( $file_name, $session_data );
|
||||
wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_upload_' . $i,
|
||||
__( 'File "%s" was successfully uploaded.', 'woocommerce-jetpack' ) ), $_FILES[ $file_name ]['name'] ) );
|
||||
// To order
|
||||
if ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ) {
|
||||
$this->add_files_to_order( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ], null );
|
||||
}
|
||||
// Action
|
||||
do_action( 'wcj_checkout_files_upload', 'upload_file',
|
||||
( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ? $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] : false ),
|
||||
$_FILES[ $file_name ]['name'] );
|
||||
}
|
||||
} else {
|
||||
wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_upload_no_file_' . $i,
|
||||
__( 'Please select file to upload!', 'woocommerce-jetpack' ) ), 'notice' );
|
||||
}
|
||||
}
|
||||
}
|
||||
// Admin file download
|
||||
if ( isset( $_GET['wcj_download_checkout_file_admin'] ) ) {
|
||||
$tmp_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $_GET['wcj_download_checkout_file_admin'];
|
||||
$file_name = get_post_meta( $_GET['post'], '_' . 'wcj_checkout_files_upload_real_name_' . $_GET['wcj_checkout_file_number'], true );
|
||||
if ( wcj_is_user_role( 'administrator' ) || is_shop_manager() ) {
|
||||
header( "Expires: 0" );
|
||||
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
|
||||
header( "Cache-Control: private", false );
|
||||
header( 'Content-disposition: attachment; filename=' . $file_name );
|
||||
header( "Content-Transfer-Encoding: binary" );
|
||||
header( "Content-Length: ". filesize( $tmp_file_name ) );
|
||||
readfile( $tmp_file_name );
|
||||
exit();
|
||||
}
|
||||
}
|
||||
// Admin all files delete
|
||||
if ( isset( $_GET['wcj_download_checkout_file_admin_delete_all'] ) && ( wcj_is_user_role( 'administrator' ) || is_shop_manager() ) ) {
|
||||
$order_id = $_GET['wcj_download_checkout_file_admin_delete_all'];
|
||||
$total_files = get_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', true );
|
||||
for ( $i = 1; $i <= $total_files; $i++ ) {
|
||||
if ( '' != ( $order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true ) ) ) {
|
||||
unlink( wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name );
|
||||
}
|
||||
delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i );
|
||||
delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i );
|
||||
}
|
||||
delete_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files' );
|
||||
wp_safe_redirect( remove_query_arg( 'wcj_download_checkout_file_admin_delete_all' ) );
|
||||
exit;
|
||||
}
|
||||
// User file download
|
||||
if ( isset( $_GET['wcj_download_checkout_file'] ) && isset( $_GET['_wpnonce'] ) && ( false !== wp_verify_nonce( $_GET['_wpnonce'], 'wcj_download_checkout_file' ) ) ) {
|
||||
$i = $_GET['wcj_download_checkout_file'];
|
||||
if ( ! empty( $_GET['wcj_download_checkout_file_order_id'] ) ) {
|
||||
$order_id = $_GET['wcj_download_checkout_file_order_id'];
|
||||
if ( ! ( $order = wc_get_order( $order_id ) ) ) {
|
||||
return;
|
||||
}
|
||||
if ( isset( $_GET['key'] ) ) {
|
||||
// Thank you page
|
||||
if ( ! $order->key_is_valid( $_GET['key'] ) ) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// My Account
|
||||
if ( ! wcj_is_user_logged_in() || $order->get_customer_id() != wcj_get_current_user_id() ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
|
||||
$tmp_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name;
|
||||
$file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
|
||||
} else {
|
||||
$session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
|
||||
$tmp_file_name = $session_data['tmp_name'];
|
||||
$file_name = $session_data['name'];
|
||||
}
|
||||
header( "Expires: 0" );
|
||||
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
|
||||
header( "Cache-Control: private", false );
|
||||
header( 'Content-disposition: attachment; filename=' . $file_name );
|
||||
header( "Content-Transfer-Encoding: binary" );
|
||||
header( "Content-Length: ". filesize( $tmp_file_name ) );
|
||||
readfile( $tmp_file_name );
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* is_visible.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.4.7
|
||||
*/
|
||||
function is_visible( $i, $order_id = 0 ) {
|
||||
|
||||
if ( apply_filters( 'wcj_checkout_files_always_visible_on_empty_cart', false ) && 0 == $order_id && WC()->cart->is_empty() ) {
|
||||
// Added for "One Page Checkout" plugin compatibility.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Include by user role
|
||||
$user_roles = get_option( 'wcj_checkout_files_upload_show_user_roles_' . $i, '' );
|
||||
if ( ! empty( $user_roles ) && ! in_array( wcj_get_current_user_first_role(), $user_roles ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exclude by user role
|
||||
$user_roles = get_option( 'wcj_checkout_files_upload_hide_user_roles_' . $i, '' );
|
||||
if ( ! empty( $user_roles ) && in_array( wcj_get_current_user_first_role(), $user_roles ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Include by product id
|
||||
$products_in = get_option( 'wcj_checkout_files_upload_show_products_in_' . $i );
|
||||
if ( ! empty( $products_in ) ) {
|
||||
$do_skip_by_products = true;
|
||||
if ( 0 != $order_id ) {
|
||||
$the_order = wc_get_order( $order_id );
|
||||
$the_items = $the_order->get_items();
|
||||
} else {
|
||||
$the_items = WC()->cart->get_cart();
|
||||
}
|
||||
foreach ( $the_items as $cart_item_key => $values ) {
|
||||
if ( in_array( $values['product_id'], $products_in ) ) {
|
||||
$do_skip_by_products = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( $do_skip_by_products ) return false;
|
||||
}
|
||||
|
||||
// Exclude by product id
|
||||
$products_in = get_option( 'wcj_checkout_files_upload_hide_products_in_' . $i );
|
||||
if ( ! empty( $products_in ) ) {
|
||||
if ( 0 != $order_id ) {
|
||||
$the_order = wc_get_order( $order_id );
|
||||
$the_items = $the_order->get_items();
|
||||
} else {
|
||||
$the_items = WC()->cart->get_cart();
|
||||
}
|
||||
foreach ( $the_items as $cart_item_key => $values ) {
|
||||
if ( in_array( $values['product_id'], $products_in ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Include by product category
|
||||
$categories_in = get_option( 'wcj_checkout_files_upload_show_cats_in_' . $i );
|
||||
if ( ! empty( $categories_in ) ) {
|
||||
$do_skip_by_cats = true;
|
||||
if ( 0 != $order_id ) {
|
||||
$the_order = wc_get_order( $order_id );
|
||||
$the_items = $the_order->get_items();
|
||||
} else {
|
||||
$the_items = WC()->cart->get_cart();
|
||||
}
|
||||
foreach ( $the_items as $cart_item_key => $values ) {
|
||||
$product_categories = get_the_terms( $values['product_id'], 'product_cat' );
|
||||
if ( empty( $product_categories ) ) continue;
|
||||
foreach( $product_categories as $product_category ) {
|
||||
if ( in_array( $product_category->term_id, $categories_in ) ) {
|
||||
$do_skip_by_cats = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! $do_skip_by_cats ) break;
|
||||
}
|
||||
if ( $do_skip_by_cats ) return false;
|
||||
}
|
||||
|
||||
// Exclude by product category
|
||||
$categories_in = get_option( 'wcj_checkout_files_upload_hide_cats_in_' . $i );
|
||||
if ( ! empty( $categories_in ) ) {
|
||||
if ( 0 != $order_id ) {
|
||||
$the_order = wc_get_order( $order_id );
|
||||
$the_items = $the_order->get_items();
|
||||
} else {
|
||||
$the_items = WC()->cart->get_cart();
|
||||
}
|
||||
foreach ( $the_items as $cart_item_key => $values ) {
|
||||
$product_categories = get_the_terms( $values['product_id'], 'product_cat' );
|
||||
if ( empty( $product_categories ) ) continue;
|
||||
foreach( $product_categories as $product_category ) {
|
||||
if ( in_array( $product_category->term_id, $categories_in ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Include by product tag
|
||||
$tags_in = get_option( 'wcj_checkout_files_upload_show_tags_in_' . $i );
|
||||
if ( ! empty( $tags_in ) ) {
|
||||
$do_skip_by_tags = true;
|
||||
if ( 0 != $order_id ) {
|
||||
$the_order = wc_get_order( $order_id );
|
||||
$the_items = $the_order->get_items();
|
||||
} else {
|
||||
$the_items = WC()->cart->get_cart();
|
||||
}
|
||||
foreach ( $the_items as $cart_item_key => $values ) {
|
||||
$product_tags = get_the_terms( $values['product_id'], 'product_tag' );
|
||||
if ( empty( $product_tags ) ) continue;
|
||||
foreach( $product_tags as $product_tag ) {
|
||||
if ( in_array( $product_tag->term_id, $tags_in ) ) {
|
||||
$do_skip_by_tags = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! $do_skip_by_tags ) break;
|
||||
}
|
||||
if ( $do_skip_by_tags ) return false;
|
||||
}
|
||||
|
||||
// Exclude by product tag
|
||||
$tags_in = get_option( 'wcj_checkout_files_upload_hide_tags_in_' . $i );
|
||||
if ( ! empty( $tags_in ) ) {
|
||||
if ( 0 != $order_id ) {
|
||||
$the_order = wc_get_order( $order_id );
|
||||
$the_items = $the_order->get_items();
|
||||
} else {
|
||||
$the_items = WC()->cart->get_cart();
|
||||
}
|
||||
foreach ( $the_items as $cart_item_key => $values ) {
|
||||
$product_tags = get_the_terms( $values['product_id'], 'product_tag' );
|
||||
if ( empty( $product_tags ) ) continue;
|
||||
foreach( $product_tags as $product_tag ) {
|
||||
if ( in_array( $product_tag->term_id, $tags_in ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_get_image.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.7.0
|
||||
*/
|
||||
function maybe_get_image( $link, $i, $order_id = 0 ) {
|
||||
if ( 'yes' === get_option( 'wcj_checkout_files_upload_form_template_field_show_images', 'no' ) ) {
|
||||
if ( 0 != $order_id && isset( $_GET['key'] ) && ( $order = wc_get_order( $order_id ) ) && $order->key_is_valid( $_GET['key'] ) ) {
|
||||
$order_file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i, true );
|
||||
$tmp_file_name = wcj_get_wcj_uploads_dir( 'checkout_files_upload' ) . '/' . $order_file_name;
|
||||
} else {
|
||||
$session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
|
||||
$tmp_file_name = $session_data['tmp_name'];
|
||||
}
|
||||
if ( @is_array( getimagesize( $tmp_file_name ) ) ) {
|
||||
return '<img style="' . get_option( 'wcj_checkout_files_upload_form_template_field_image_style', 'width:64px;' ) . '" src="' . $link. '"> ';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* get_the_form.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function get_the_form( $i, $file_name, $order_id = 0 ) {
|
||||
$html = '';
|
||||
$html .= '<form enctype="multipart/form-data" action="" method="POST">';
|
||||
$html .= get_option( 'wcj_checkout_files_upload_form_template_before', '<table>' );
|
||||
if ( '' != ( $the_label = get_option( 'wcj_checkout_files_upload_label_' . $i, '' ) ) ) {
|
||||
$template = get_option( 'wcj_checkout_files_upload_form_template_label',
|
||||
'<tr><td colspan="2"><label for="%field_id%">%field_label%</label>%required_html%</td></tr>' );
|
||||
$required_html = ( 'yes' === get_option( 'wcj_checkout_files_upload_required_' . $i, 'no' ) ) ?
|
||||
' <abbr class="required" title="required">*</abbr>' : '';
|
||||
$html .= str_replace(
|
||||
array( '%field_id%', '%field_label%', '%required_html%' ),
|
||||
array( 'wcj_checkout_files_upload_' . $i, $the_label, $required_html ),
|
||||
$template
|
||||
);
|
||||
}
|
||||
if ( '' == $file_name ) {
|
||||
$field_html = '<input type="file" name="wcj_checkout_files_upload_' . $i . '" id="wcj_checkout_files_upload_' . $i .
|
||||
'" accept="' . get_option( 'wcj_checkout_files_upload_file_accept_' . $i, '' ) . '">';
|
||||
$button_html = '<input type="submit"' .
|
||||
' class="button alt"' .
|
||||
' style="width:100%;"' .
|
||||
' name="wcj_upload_checkout_file_' . $i . '"' .
|
||||
' id="wcj_upload_checkout_file_' . $i . '"' .
|
||||
' value="' . get_option( 'wcj_checkout_files_upload_label_upload_button_' . $i, __( 'Upload', 'woocommerce-jetpack' ) ) . '"' .
|
||||
' data-value="' . get_option( 'wcj_checkout_files_upload_label_upload_button_' . $i, __( 'Upload', 'woocommerce-jetpack' ) ) . '">';
|
||||
} else {
|
||||
$link = add_query_arg( array( 'wcj_download_checkout_file' => $i, '_wpnonce' => wp_create_nonce( 'wcj_download_checkout_file' ), 'wcj_download_checkout_file_order_id' => $order_id ) );
|
||||
$field_html = '<a href="' . $link . '">' . $this->maybe_get_image( $link, $i, $order_id ) . $file_name . '</a>';
|
||||
$button_html = '<input type="submit"' .
|
||||
' class="button"' .
|
||||
' style="width:100%;"' .
|
||||
' name="wcj_remove_checkout_file_' . $i . '"' .
|
||||
' id="wcj_remove_checkout_file_' . $i . '"' .
|
||||
' value="' . get_option( 'wcj_checkout_files_upload_label_remove_button_' . $i, __( 'Remove', 'woocommerce-jetpack' ) ) . '"' .
|
||||
' data-value="' . get_option( 'wcj_checkout_files_upload_label_remove_button_' . $i, __( 'Remove', 'woocommerce-jetpack' ) ) . '">';
|
||||
}
|
||||
$template = get_option( 'wcj_checkout_files_upload_form_template_field',
|
||||
'<tr><td style="width:50%;">%field_html%</td><td style="width:50%;">%button_html%</td></tr>' );
|
||||
$html .= str_replace(
|
||||
array( '%field_html%', '%button_html%' ),
|
||||
array( $field_html, $button_html ),
|
||||
$template
|
||||
);
|
||||
$html .= get_option( 'wcj_checkout_files_upload_form_template_after', '</table>' );
|
||||
if ( 0 != $order_id ) {
|
||||
$html .= '<input type="hidden" name="wcj_checkout_files_upload_order_id_' . $i . '" value="' . $order_id . '">';
|
||||
}
|
||||
$html .= '</form>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_files_upload_form_to_thankyou_and_myaccount_page.
|
||||
*
|
||||
* @version 2.5.6
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_files_upload_form_to_thankyou_and_myaccount_page( $order_id ) {
|
||||
$html = '';
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
|
||||
$current_filter = current_filter();
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_checkout_files_upload_enabled_' . $i, 'yes' ) && $this->is_visible( $i, $order_id ) ) {
|
||||
if (
|
||||
( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_thankyou_' . $i, 'no' ) && 'woocommerce_thankyou' === $current_filter ) ||
|
||||
( 'yes' === get_option( 'wcj_checkout_files_upload_add_to_myaccount_' . $i, 'no' ) && 'woocommerce_view_order' === $current_filter )
|
||||
) {
|
||||
$file_name = get_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i, true );
|
||||
$html .= $this->get_the_form( $i, $file_name, $order_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_files_upload_form_to_checkout_frontend.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.4.5
|
||||
*/
|
||||
function add_files_upload_form_to_checkout_frontend() {
|
||||
$this->add_files_upload_form_to_checkout_frontend_all();
|
||||
}
|
||||
|
||||
/**
|
||||
* add_files_upload_form_to_checkout_frontend_all.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_files_upload_form_to_checkout_frontend_all( $is_direct_call = false ) {
|
||||
$html = '';
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
|
||||
if ( ! $is_direct_call ) {
|
||||
$current_filter = current_filter();
|
||||
$current_filter_priority = wcj_current_filter_priority();
|
||||
}
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
$is_filter_ok = ( $is_direct_call ) ? true : (
|
||||
$current_filter === get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' ) &&
|
||||
$current_filter_priority == get_option( 'wcj_checkout_files_upload_hook_priority_' . $i, 10 )
|
||||
);
|
||||
if ( 'yes' === get_option( 'wcj_checkout_files_upload_enabled_' . $i, 'yes' ) && $is_filter_ok && $this->is_visible( $i ) ) {
|
||||
$session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
|
||||
$file_name = ( null !== $session_data ? $session_data['name'] : '' );
|
||||
$html .= $this->get_the_form( $i, $file_name );
|
||||
}
|
||||
}
|
||||
echo $html;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Checkout_Files_Upload();
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Coupon by User Role
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Coupon_By_User_Role' ) ) :
|
||||
|
||||
class WCJ_Coupon_By_User_Role extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @todo (maybe) init all options in constructor
|
||||
* @todo (maybe) use another error code (instead of 10000)
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'coupon_by_user_role';
|
||||
$this->short_desc = __( 'Coupon by User Role', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Coupons by user roles.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-coupon-by-user-role';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_coupons_enabled', array( $this, 'coupons_enabled' ), PHP_INT_MAX, 1 );
|
||||
add_filter( 'woocommerce_coupon_is_valid', array( $this, 'coupon_valid' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_coupon_error', array( $this, 'coupon_not_valid_message' ), PHP_INT_MAX, 3 );
|
||||
if ( $this->invalid_per_coupon_enabled = ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_coupon_by_user_role_invalid_per_coupon', 'no' ) ) ) ) {
|
||||
$this->meta_box_screen = 'shop_coupon';
|
||||
$this->meta_box_context = 'side';
|
||||
$this->meta_box_priority = 'default';
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_shop_coupon', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* coupons_enabled.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function coupons_enabled( $is_enabled ) {
|
||||
$disabled_user_roles = get_option( 'wcj_coupon_by_user_role_disabled', '' );
|
||||
if ( ! empty( $disabled_user_roles ) && in_array( wcj_get_current_user_first_role(), $disabled_user_roles ) ) {
|
||||
return false;
|
||||
}
|
||||
return $is_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* coupon_valid.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @todo (maybe) check if `$coupon->get_id()` is working in WC below v3.0.0
|
||||
*/
|
||||
function coupon_valid( $valid, $coupon, $discounts ) {
|
||||
$invalid_user_roles = get_option( 'wcj_coupon_by_user_role_invalid', '' );
|
||||
if ( empty( $invalid_user_roles ) ) {
|
||||
$invalid_user_roles = array();
|
||||
}
|
||||
if ( $this->invalid_per_coupon_enabled ) {
|
||||
$invalid_user_roles_per_coupon = get_post_meta( $coupon->get_id(), '_' . 'wcj_coupon_by_user_role_invalid', true );
|
||||
if ( ! empty( $invalid_user_roles_per_coupon ) ) {
|
||||
$invalid_user_roles = array_merge( $invalid_user_roles, $invalid_user_roles_per_coupon );
|
||||
}
|
||||
}
|
||||
if ( ! empty( $invalid_user_roles ) && in_array( wcj_get_current_user_first_role(), $invalid_user_roles ) ) {
|
||||
throw new Exception( apply_filters( 'booster_option', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ),
|
||||
get_option( 'wcj_coupon_by_user_role_invalid_message', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ) ) ), 10000 );
|
||||
return false;
|
||||
}
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* coupon_not_valid_message.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function coupon_not_valid_message( $message, $code, $coupon ) {
|
||||
if ( 10000 === $code ) {
|
||||
return apply_filters( 'booster_option', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ),
|
||||
get_option( 'wcj_coupon_by_user_role_invalid_message', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ) ) );
|
||||
}
|
||||
return $message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Coupon_By_User_Role();
|
||||
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Coupon Code Generator
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @since 3.2.3
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Coupon_Code_Generator' ) ) :
|
||||
|
||||
class WCJ_Coupon_Code_Generator extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @since 3.2.3
|
||||
* @todo user ID in coupon code
|
||||
* @todo add option to generate code only on button (in meta box) pressed
|
||||
* @todo `wp_ajax_nopriv_wcj_generate_coupon_code` ?
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'coupon_code_generator';
|
||||
$this->short_desc = __( 'Coupon Code Generator', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Coupon code generator.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-coupon-code-generator';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( 'yes' === get_option( 'wcj_coupons_code_generator_enabled', 'no' ) ) {
|
||||
add_action( 'wp_ajax_wcj_generate_coupon_code', array( $this, 'ajax_generate_coupon_code' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_generate_coupon_code_script' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_generate_coupon_code_script.
|
||||
*
|
||||
* @version 3.1.3
|
||||
* @since 3.1.3
|
||||
*/
|
||||
function enqueue_generate_coupon_code_script() {
|
||||
global $pagenow;
|
||||
if ( 'post-new.php' === $pagenow && isset( $_GET['post_type'] ) && 'shop_coupon' === $_GET['post_type'] ) {
|
||||
wp_enqueue_script( 'wcj-coupons-code-generator', wcj_plugin_url() . '/includes/js/wcj-coupons-code-generator.js', array( 'jquery' ), WCJ()->version, true );
|
||||
wp_localize_script( 'wcj-coupons-code-generator', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* random_string.
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @since 3.2.3
|
||||
* @todo (maybe) $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
*/
|
||||
function random_string( $length = 32, $characters = 'abcdefghijklmnopqrstuvwxyz' ) {
|
||||
$characters_length = strlen( $characters );
|
||||
$random_string = '';
|
||||
for ( $i = 0; $i < $length; $i++ ) {
|
||||
$random_string .= $characters[ rand( 0, $characters_length - 1 ) ];
|
||||
}
|
||||
return $random_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate_coupon_code.
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @since 3.1.3
|
||||
* @todo (maybe) more algorithms
|
||||
*/
|
||||
function generate_coupon_code( $str = '', $algorithm = '', $length = '' ) {
|
||||
if ( '' === $str ) {
|
||||
$str = time();
|
||||
}
|
||||
if ( '' === $algorithm ) {
|
||||
$algorithm = apply_filters( 'booster_option', 'crc32', get_option( 'wcj_coupons_code_generator_algorithm', 'crc32' ) );
|
||||
}
|
||||
switch ( $algorithm ) {
|
||||
case 'random_letters_and_numbers':
|
||||
$code = $this->random_string( 32, '0123456789abcdefghijklmnopqrstuvwxyz' );
|
||||
break;
|
||||
case 'random_letters':
|
||||
$code = $this->random_string( 32, 'abcdefghijklmnopqrstuvwxyz' );
|
||||
break;
|
||||
case 'random_numbers':
|
||||
$code = $this->random_string( 32, '0123456789' );
|
||||
break;
|
||||
case 'md5':
|
||||
$code = md5( $str );
|
||||
break;
|
||||
case 'sha1':
|
||||
$code = sha1( $str );
|
||||
break;
|
||||
default: // 'crc32'
|
||||
$code = sprintf( '%08x', crc32( $str ) );
|
||||
break;
|
||||
}
|
||||
if ( '' === $length ) {
|
||||
$length = apply_filters( 'booster_option', 0, get_option( 'wcj_coupons_code_generator_length', 0 ) );
|
||||
}
|
||||
if ( $length > 0 && strlen( $code ) > $length ) {
|
||||
$code = substr( $code, 0, $length );
|
||||
}
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* ajax_generate_coupon_code.
|
||||
*
|
||||
* @version 3.1.3
|
||||
* @since 3.1.3
|
||||
* @todo (maybe) optionally generate some description for coupon (e.g. "Automatically generated coupon [YYYY-MM-DD]")
|
||||
*/
|
||||
function ajax_generate_coupon_code() {
|
||||
$attempts = 0;
|
||||
while ( true ) {
|
||||
$coupon_code = $this->generate_coupon_code();
|
||||
$coupon = new WC_Coupon( $coupon_code );
|
||||
if ( ! $coupon->get_id() ) {
|
||||
echo $coupon_code;
|
||||
die();
|
||||
}
|
||||
$attempts++;
|
||||
if ( $attempts > 100 ) { // shouldn't happen, but just in case...
|
||||
echo '';
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Coupon_Code_Generator();
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Cross-sells
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.5.3
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Cross_Sells' ) ) :
|
||||
|
||||
class WCJ_Cross_Sells extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.5.3
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'cross_sells';
|
||||
$this->short_desc = __( 'Cross-sells', 'woocommerce-jetpack' );
|
||||
$this->extra_desc = __( 'Cross-sells are products which you promote in the cart, based on the current product.', 'woocommerce' ) . '<br>' .
|
||||
sprintf( __( 'You can also use %s shortcode to display cross-sells anywhere on your site, for example on checkout page with %s module.', 'woocommerce-jetpack' ),
|
||||
'<code>[wcj_cross_sell_display]</code>',
|
||||
'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=cart_and_checkout§ion=checkout_custom_info' ) . '">' .
|
||||
__( 'Checkout Custom Info', 'woocommerce-jetpack' ) . '</a>' );
|
||||
$this->desc = __( 'Customize cross-sells products display.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-cross-sells';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_cross_sells_total', array( $this, 'cross_sells_total' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_cross_sells_columns', array( $this, 'cross_sells_columns' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_cross_sells_orderby', array( $this, 'cross_sells_orderby' ), PHP_INT_MAX );
|
||||
if ( ! WCJ_IS_WC_VERSION_BELOW_3_3_0 ) {
|
||||
add_filter( 'woocommerce_cross_sells_order', array( $this, 'cross_sells_order' ), PHP_INT_MAX );
|
||||
}
|
||||
if ( ! WCJ_IS_WC_VERSION_BELOW_3 ) {
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_cross_sells_global_enabled', 'no' ) ) ) {
|
||||
add_filter( 'woocommerce_product_get_cross_sell_ids', array( $this, 'cross_sells_ids' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_cross_sells_hide', 'no' ) ) {
|
||||
add_action( 'init', array( $this, 'hide_cross_sells' ), PHP_INT_MAX );
|
||||
}
|
||||
if ( 'no_changes' != get_option( 'wcj_cross_sells_position', 'no_changes' ) ) {
|
||||
add_action( 'init', array( $this, 'reposition_cross_sells' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* reposition_cross_sells.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @todo (maybe) check `woocommerce\templates\cart\cart.php` for more positions
|
||||
*/
|
||||
function reposition_cross_sells() {
|
||||
$this->hide_cross_sells();
|
||||
add_action( get_option( 'wcj_cross_sells_position', 'no_changes' ), 'woocommerce_cross_sell_display', get_option( 'wcj_cross_sells_position_priority', 10 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_cross_sells.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function hide_cross_sells() {
|
||||
remove_action( 'woocommerce_cart_collaterals', 'woocommerce_cross_sell_display' );
|
||||
}
|
||||
|
||||
/**
|
||||
* cross_sells_ids.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @todo (maybe) on per category/tag basis
|
||||
* @todo (maybe) ids instead of list
|
||||
* @todo (maybe) on cart update (i.e. product removed) cross-sells are not updated (so it may be needed to reload page manually to see new cross-sells)
|
||||
*/
|
||||
function cross_sells_ids( $ids, $_product ) {
|
||||
$global_cross_sells = get_option( 'wcj_cross_sells_global_ids', '' );
|
||||
if ( ! empty( $global_cross_sells ) ) {
|
||||
$global_cross_sells = array_unique( $global_cross_sells );
|
||||
$product_id = wcj_get_product_id_or_variation_parent_id( $_product );
|
||||
if ( false !== ( $key = array_search( $product_id, $global_cross_sells ) ) ) {
|
||||
unset( $global_cross_sells[ $key ] );
|
||||
}
|
||||
}
|
||||
return ( empty( $global_cross_sells ) ? $ids : array_unique( array_merge( $ids, $global_cross_sells ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* cross_sells_order.
|
||||
*
|
||||
* @version 3.5.3
|
||||
* @since 3.5.3
|
||||
*/
|
||||
function cross_sells_order( $order ) {
|
||||
return ( 'no_changes' != ( $_order = get_option( 'wcj_cross_sells_order', 'no_changes' ) ) ? $_order : $order );
|
||||
}
|
||||
|
||||
/**
|
||||
* cross_sells_orderby.
|
||||
*
|
||||
* @version 3.5.3
|
||||
* @since 3.5.3
|
||||
*/
|
||||
function cross_sells_orderby( $orderby ) {
|
||||
return ( 'no_changes' != ( $_orderby = get_option( 'wcj_cross_sells_orderby', 'no_changes' ) ) ? $_orderby : $orderby );
|
||||
}
|
||||
|
||||
/**
|
||||
* cross_sells_columns.
|
||||
*
|
||||
* @version 3.5.3
|
||||
* @since 3.5.3
|
||||
*/
|
||||
function cross_sells_columns( $columns ) {
|
||||
return ( 0 != ( $_columns = get_option( 'wcj_cross_sells_columns', 0 ) ) ? $_columns : $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* cross_sells_total.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.5.3
|
||||
*/
|
||||
function cross_sells_total( $limit ) {
|
||||
return ( 0 != ( $_limit = get_option( 'wcj_cross_sells_total', 0 ) ) ? $_limit : $limit );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Cross_Sells();
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Crowdfunding
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.2.6
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Crowdfunding' ) ) :
|
||||
|
||||
class WCJ_Crowdfunding extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'crowdfunding';
|
||||
$this->short_desc = __( 'Crowdfunding', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add crowdfunding products to WooCommerce.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-crowdfunding';
|
||||
$this->extra_desc = __( 'When enabled, module will add Crowdfunding metabox to product edit.', 'woocommerce-jetpack' ) . '<br>' .
|
||||
sprintf(
|
||||
__( 'To add crowdfunding info to the product, use <a href="%s" target="_blank">Booster\'s crowdfunding shortcodes</a>.', 'woocommerce-jetpack' ),
|
||||
'https://booster.io/category/shortcodes/products-crowdfunding/'
|
||||
) . ' ' .
|
||||
sprintf(
|
||||
__( 'Shortcodes could be used for example in <a href="%s">Product Info module</a>.', 'woocommerce-jetpack' ),
|
||||
admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=products§ion=product_custom_info' )
|
||||
) . '<br>' .
|
||||
sprintf(
|
||||
__( 'To change add to cart button labels use <a href="%s">Add to Cart Labels module</a>.', 'woocommerce-jetpack' ),
|
||||
admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=labels§ion=add_to_cart' )
|
||||
);
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
|
||||
add_action( 'woocommerce_is_purchasable', array( $this, 'check_dates' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check_dates.
|
||||
*
|
||||
* @version 2.7.0
|
||||
*/
|
||||
function check_dates( $purchasable, $_product ) {
|
||||
$_product_id = wcj_get_product_id_or_variation_parent_id( $_product );
|
||||
$goal = get_post_meta( $_product_id, '_' . 'wcj_crowdfunding_goal_sum', true );
|
||||
if ( 0 != $goal ) {
|
||||
$start_date_str = get_post_meta( $_product_id, '_' . 'wcj_crowdfunding_startdate', true );
|
||||
$end_date_str = get_post_meta( $_product_id, '_' . 'wcj_crowdfunding_deadline', true );
|
||||
$start_date = ( '' != $start_date_str ) ? strtotime( $start_date_str ) : 0;
|
||||
$end_date = ( '' != $end_date_str ) ? strtotime( $end_date_str ) : 0;
|
||||
if ( $start_date > 0 && ( $start_date - current_time( 'timestamp' ) ) > 0 ) {
|
||||
$purchasable = false;
|
||||
}
|
||||
if ( $end_date > 0 && ( $end_date - current_time( 'timestamp' ) ) < 0 ) {
|
||||
$purchasable = false;
|
||||
}
|
||||
}
|
||||
return $purchasable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Crowdfunding();
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Currencies
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Currencies' ) ) :
|
||||
|
||||
class WCJ_Currencies extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.4
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'currency';
|
||||
$this->short_desc = __( 'Currencies', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add all world currencies and cryptocurrencies to your store; change currency symbol.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-all-currencies';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_currencies', array( $this, 'add_all_currencies'), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol'), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_general_settings', array( $this, 'add_edit_currency_symbol_field' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_all_currencies - changing currency code.
|
||||
*
|
||||
* @version 2.4.4
|
||||
*/
|
||||
function add_all_currencies( $currencies ) {
|
||||
$currency_names = wcj_get_currencies_names_and_symbols( 'names' );
|
||||
foreach ( $currency_names as $currency_code => $currency_name ) {
|
||||
$currencies[ $currency_code ] = $currency_name;
|
||||
}
|
||||
asort( $currencies );
|
||||
return $currencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_currency_symbol.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function change_currency_symbol( $currency_symbol, $currency ) {
|
||||
return ( 'yes' === get_option( 'wcj_currency_hide_symbol', 'no' ) ? '' : wcj_get_currency_symbol( $currency ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_edit_currency_symbol_field.
|
||||
*
|
||||
* @version 2.4.0
|
||||
* @todo (maybe) remove this
|
||||
*/
|
||||
function add_edit_currency_symbol_field( $settings ) {
|
||||
$updated_settings = array();
|
||||
foreach ( $settings as $section ) {
|
||||
if ( isset( $section['id'] ) && 'woocommerce_currency_pos' == $section['id'] ) {
|
||||
$updated_settings[] = array(
|
||||
'name' => __( 'Booster: Currency Symbol', 'woocommerce-jetpack' ),
|
||||
'desc_tip' => __( 'This sets the currency symbol.', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_currency_' . get_woocommerce_currency(),
|
||||
'type' => 'text',
|
||||
'default' => get_woocommerce_currency_symbol(),
|
||||
'desc' => apply_filters( 'booster_message', '', 'desc' ),
|
||||
'css' => 'width: 50px;',
|
||||
'custom_attributes' => apply_filters( 'booster_message', '', 'readonly' ),
|
||||
);
|
||||
}
|
||||
$updated_settings[] = $section;
|
||||
}
|
||||
return $updated_settings;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Currencies();
|
||||
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Currency Exchange Rates
|
||||
*
|
||||
* @version 3.4.5
|
||||
* @since 2.3.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Currency_Exchange_Rates' ) ) :
|
||||
|
||||
class WCJ_Currency_Exchange_Rates extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.4.5
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'currency_exchange_rates';
|
||||
$this->short_desc = __( 'Currency Exchange Rates', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Automatic currency exchange rates for WooCommerce.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-currency-exchange-rates';
|
||||
parent::__construct();
|
||||
|
||||
add_action( 'wp_ajax_' . 'wcj_ajax_get_exchange_rates', array( $this, 'wcj_ajax_get_exchange_rates' ) );
|
||||
add_action( 'wp_ajax_nopriv_' . 'wcj_ajax_get_exchange_rates', array( $this, 'wcj_ajax_get_exchange_rates' ) );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
include_once( 'exchange-rates/class-wcj-exchange-rates-crons.php' );
|
||||
add_action( 'admin_init', array( $this, 'maybe_update_all_rates' ) );
|
||||
}
|
||||
include_once( 'exchange-rates/class-wcj-exchange-rates.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_update_all_rates.
|
||||
*
|
||||
* @version 3.4.5
|
||||
* @since 3.4.5
|
||||
*/
|
||||
function maybe_update_all_rates() {
|
||||
if ( isset( $_GET['wcj_currency_exchange_rates_update_now'] ) ) {
|
||||
do_action( 'auto_update_exchange_rates_hook' );
|
||||
wp_safe_redirect( remove_query_arg( 'wcj_currency_exchange_rates_update_now' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wcj_ajax_get_exchange_rates.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.6.0
|
||||
* @todo (maybe) move this to `class-wcj-exchange-rates.php`
|
||||
*/
|
||||
function wcj_ajax_get_exchange_rates() {
|
||||
echo wcj_get_exchange_rate( $_POST['wcj_currency_from'], $_POST['wcj_currency_to'] );
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* add_currency_pair_setting.
|
||||
*
|
||||
* @version 3.2.4
|
||||
*/
|
||||
function add_currency_pair_setting( $currency_from, $currency_to, $settings ) {
|
||||
if ( $currency_from != $currency_to ) {
|
||||
$field_id = 'wcj_currency_exchange_rates_' . sanitize_title( $currency_from . $currency_to );
|
||||
foreach ( $settings as $setting ) {
|
||||
if ( $setting['id'] === $field_id ) {
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
$custom_attributes = array(
|
||||
'currency_from' => $currency_from,
|
||||
'currency_to' => $currency_to,
|
||||
'multiply_by_field_id' => $field_id,
|
||||
);
|
||||
$settings[] = array(
|
||||
'title' => $currency_from . ' / ' . $currency_to,
|
||||
'id' => $field_id,
|
||||
'default' => 0,
|
||||
'type' => 'exchange_rate',
|
||||
'custom_attributes_button' => $custom_attributes,
|
||||
'value' => $currency_from . '/' . $currency_to,
|
||||
);
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_all_currencies_exchange_rates_currencies.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function get_all_currencies_exchange_rates_currencies() {
|
||||
$currencies = array();
|
||||
// Additional currencies (via filter)
|
||||
$additional_currencies = apply_filters( 'wcj_currency_exchange_rates_additional_currencies', array() );
|
||||
foreach ( $additional_currencies as $additional_currency ) {
|
||||
$currencies[] = $additional_currency;
|
||||
}
|
||||
// Additional currencies (via custom currencies section)
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_exchange_custom_currencies_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( 'disabled' != ( $additional_currency = get_option( 'wcj_currency_exchange_custom_currencies_' . $i, 'disabled' ) ) ) {
|
||||
$currencies[] = $additional_currency;
|
||||
}
|
||||
}
|
||||
if ( wcj_is_module_enabled( 'price_by_country' ) ) {
|
||||
// Currency Pairs - Price by Country
|
||||
if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_price_by_country_auto_exchange_rates', 'manual' ) ) ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_price_by_country_total_groups_number', 1 ) ); $i++ ) {
|
||||
$currency_to = get_option( 'wcj_price_by_country_exchange_rate_currency_group_' . $i );
|
||||
$currencies[] = $currency_to;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( wcj_is_module_enabled( 'multicurrency' ) ) {
|
||||
// Currency Pairs - Multicurrency
|
||||
if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_multicurrency_exchange_rate_update_auto', 'manual' ) ) ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 2, get_option( 'wcj_multicurrency_total_number', 2 ) ); $i++ ) {
|
||||
$currency_to = get_option( 'wcj_multicurrency_currency_' . $i );
|
||||
$currencies[] = $currency_to;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( wcj_is_module_enabled( 'multicurrency_base_price' ) ) {
|
||||
// Currency Pairs - Multicurrency Product Base Price
|
||||
if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_multicurrency_base_price_exchange_rate_update', 'manual' ) ) ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_multicurrency_base_price_total_number', 1 ) ); $i++ ) {
|
||||
$currency_to = get_option( 'wcj_multicurrency_base_price_currency_' . $i );
|
||||
$currencies[] = $currency_to;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( wcj_is_module_enabled( 'currency_per_product' ) ) {
|
||||
// Currency Pairs - Currency per Product
|
||||
if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_currency_per_product_exchange_rate_update', 'manual' ) ) ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) ); $i++ ) {
|
||||
$currency_to = get_option( 'wcj_currency_per_product_currency_' . $i );
|
||||
$currencies[] = $currency_to;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( wcj_is_module_enabled( 'payment_gateways_currency' ) ) {
|
||||
if ( 'manual' != apply_filters( 'booster_option', 'manual', get_option( 'wcj_gateways_currency_exchange_rate_update_auto', 'manual' ) ) ) {
|
||||
// Currency Pairs - Gateway Currency
|
||||
global $woocommerce;
|
||||
$available_gateways = $woocommerce->payment_gateways->payment_gateways();
|
||||
foreach ( $available_gateways as $key => $gateway ) {
|
||||
$currency_to = get_option( 'wcj_gateways_currency_' . $key );
|
||||
if ( 'no_changes' != $currency_to ) {
|
||||
$currencies[] = $currency_to;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $currencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_currency_pair_server_setting.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function add_currency_pair_server_setting( $currency_from, $currency_to, $default_server, $settings ) {
|
||||
if ( $currency_from != $currency_to ) {
|
||||
$field_id = 'wcj_currency_exchange_rates_server_' . sanitize_title( $currency_from . $currency_to );
|
||||
foreach ( $settings as $setting ) {
|
||||
if ( $setting['id'] === $field_id ) {
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
$settings[] = array(
|
||||
'desc' => __( 'Exchange Rates Server', 'woocommerce-jetpack' ),
|
||||
'id' => $field_id,
|
||||
'default' => 'default_server',
|
||||
'type' => 'select',
|
||||
'options' => array_merge(
|
||||
array( 'default_server' => sprintf( __( 'Use default: %s', 'woocommerce-jetpack' ), $default_server ) ),
|
||||
wcj_get_currency_exchange_rate_servers()
|
||||
),
|
||||
);
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_currency_pair_offset_percent_setting.
|
||||
*
|
||||
* @version 3.4.5
|
||||
* @since 3.4.5
|
||||
*/
|
||||
function add_currency_pair_offset_percent_setting( $currency_from, $currency_to, $default_offset, $settings ) {
|
||||
if ( $currency_from != $currency_to ) {
|
||||
$field_id = 'wcj_currency_exchange_rates_offset_percent_' . sanitize_title( $currency_from . $currency_to );
|
||||
foreach ( $settings as $setting ) {
|
||||
if ( $setting['id'] === $field_id ) {
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
$settings[] = array(
|
||||
'desc' => __( 'Exchange Rates Offset (Percent)', 'woocommerce-jetpack' ),
|
||||
'id' => $field_id,
|
||||
'default' => 'default_offset',
|
||||
'type' => 'select',
|
||||
'options' => array(
|
||||
'default_offset' => sprintf( __( 'Use default: %s%%', 'woocommerce-jetpack' ), $default_offset ),
|
||||
'custom_offset' => __( 'Custom offset', 'woocommerce-jetpack' ),
|
||||
),
|
||||
);
|
||||
$settings[] = array(
|
||||
'desc' => __( 'Custom offset (Percent)', 'woocommerce-jetpack' ),
|
||||
'desc_tip' => __( 'Used when "Custom offset" option is selected above.', 'woocommerce-jetpack' ),
|
||||
'id' => $field_id . '_' . 'custom_offset',
|
||||
'default' => 0,
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array( 'step' => '0.001' ),
|
||||
);
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_all_currencies_exchange_rates_settings.
|
||||
*
|
||||
* @version 3.4.5
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function get_all_currencies_exchange_rates_settings( $add_extra_settings = false ) {
|
||||
if ( $add_extra_settings ) {
|
||||
// Server
|
||||
$exchange_rate_servers = wcj_get_currency_exchange_rate_servers();
|
||||
$exchange_rate_server = get_option( 'wcj_currency_exchange_rates_server', 'ecb' );
|
||||
$default_server = ( isset( $exchange_rate_servers[ $exchange_rate_server ] ) ? $exchange_rate_servers[ $exchange_rate_server ] : $exchange_rate_server );
|
||||
// Offset
|
||||
$default_offset = get_option( 'wcj_currency_exchange_rates_offset_percent', 0 );
|
||||
}
|
||||
$settings = array();
|
||||
$currency_from = get_option( 'woocommerce_currency' );
|
||||
$currencies = $this->get_all_currencies_exchange_rates_currencies();
|
||||
foreach ( $currencies as $currency ) {
|
||||
$settings = $this->add_currency_pair_setting( $currency_from, $currency, $settings );
|
||||
if ( $add_extra_settings ) {
|
||||
$settings = $this->add_currency_pair_server_setting( $currency_from, $currency, $default_server, $settings );
|
||||
$settings = $this->add_currency_pair_offset_percent_setting( $currency_from, $currency, $default_offset, $settings );
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Currency_Exchange_Rates();
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Currency for External Products
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Currency_External_Products' ) ) :
|
||||
|
||||
class WCJ_Currency_External_Products extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'currency_external_products';
|
||||
$this->short_desc = __( 'Currency for External Products', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set different currency for external products.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-currency-for-external-products';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( '' != get_option( 'wcj_currency_external_products_symbol', 'EUR' ) ) {
|
||||
add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_currency_code.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.4.4
|
||||
*/
|
||||
function change_currency_code( $currency ) {
|
||||
global $product;
|
||||
if ( is_object( $product ) && $product->is_type( 'external' ) ) {
|
||||
return get_option( 'wcj_currency_external_products_symbol', 'EUR' );
|
||||
}
|
||||
return $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_currency_symbol.
|
||||
*
|
||||
* @version 2.7.0
|
||||
*/
|
||||
function change_currency_symbol( $currency_symbol, $currency ) {
|
||||
global $product;
|
||||
if ( is_object( $product ) && $product->is_type( 'external' ) ) {
|
||||
return wcj_get_currency_symbol( get_option( 'wcj_currency_external_products_symbol', 'EUR' ) );
|
||||
}
|
||||
return $currency_symbol;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Currency_External_Products();
|
||||
@@ -0,0 +1,508 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Currency per Product
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.2
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Currency_Per_Product' ) ) :
|
||||
|
||||
class WCJ_Currency_Per_Product extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.2
|
||||
* @todo (maybe) add `$this->price_hooks_priority`
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'currency_per_product';
|
||||
$this->short_desc = __( 'Currency per Product', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Display prices for products in different currencies.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-currency-per-product';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
$this->do_save_converted_prices = ( 'yes' === get_option( 'wcj_currency_per_product_save_prices', 'no' ) );
|
||||
|
||||
$this->is_currency_per_product_by_product_enabled = ( 'yes' === get_option( 'wcj_currency_per_product_per_product', 'yes' ) );
|
||||
if ( $this->is_currency_per_product_by_product_enabled ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
// Currency code and symbol
|
||||
add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), PHP_INT_MAX );
|
||||
|
||||
// Add to cart
|
||||
add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_cart_item_data' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_add_cart_item', array( $this, 'add_cart_item' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_from_session' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_on_add_to_cart' ), PHP_INT_MAX, 2 );
|
||||
|
||||
// Price
|
||||
add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'change_price' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_product_variation_get_price', array( $this, 'change_price' ), PHP_INT_MAX, 2 );
|
||||
|
||||
// Grouped
|
||||
add_filter( 'woocommerce_grouped_price_html', array( $this, 'grouped_price_html' ), PHP_INT_MAX, 2 );
|
||||
|
||||
// Shipping
|
||||
add_filter( 'woocommerce_package_rates', array( $this, 'change_shipping_price' ), PHP_INT_MAX, 2 );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_shipping_price.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function change_shipping_price( $package_rates, $package ) {
|
||||
if ( isset( WC()->cart ) ) {
|
||||
if ( WC()->cart->is_empty() ) {
|
||||
return $package_rates;
|
||||
}
|
||||
$cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
|
||||
switch ( $cart_checkout_behaviour ) {
|
||||
case 'leave_one_product':
|
||||
case 'leave_same_currency':
|
||||
case 'convert_first_product':
|
||||
case 'convert_last_product':
|
||||
$shop_currency = get_option( 'woocommerce_currency' );
|
||||
if ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $_currency != $shop_currency ) {
|
||||
$currency_exchange_rate = $this->get_currency_exchange_rate( $_currency );
|
||||
if ( 0 != $currency_exchange_rate && 1 != $currency_exchange_rate ) {
|
||||
$currency_exchange_rate = 1 / $currency_exchange_rate;
|
||||
return wcj_change_price_shipping_package_rates( $package_rates, $currency_exchange_rate );
|
||||
} else {
|
||||
return $package_rates;
|
||||
}
|
||||
} else {
|
||||
return $package_rates;
|
||||
}
|
||||
default: // case 'convert_shop_default':
|
||||
return $package_rates;
|
||||
}
|
||||
}
|
||||
return $package_rates;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_product_currency.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) return empty string or false, if it's shop default currency: `return ( get_option( 'woocommerce_currency' ) != ( $return = get_post_meta( $product_id, '_' . 'wcj_currency_per_product_currency', true ) ) ? $return : false );`
|
||||
*/
|
||||
function get_product_currency( $product_id ) {
|
||||
// By users or user roles
|
||||
$do_check_by_users = ( 'yes' === get_option( 'wcj_currency_per_product_by_users_enabled', 'no' ) );
|
||||
$do_check_by_user_roles = ( 'yes' === get_option( 'wcj_currency_per_product_by_user_roles_enabled', 'no' ) );
|
||||
$do_check_by_product_cats = ( 'yes' === get_option( 'wcj_currency_per_product_by_product_cats_enabled', 'no' ) );
|
||||
$do_check_by_product_tags = ( 'yes' === get_option( 'wcj_currency_per_product_by_product_tags_enabled', 'no' ) );
|
||||
if ( $do_check_by_users || $do_check_by_user_roles || $do_check_by_product_cats || $do_check_by_product_tags ) {
|
||||
if ( $do_check_by_users || $do_check_by_user_roles ) {
|
||||
$product_author_id = get_post_field( 'post_author', $product_id );
|
||||
}
|
||||
if ( $do_check_by_product_cats ) {
|
||||
$_product_cats = wcj_get_the_terms( $product_id, 'product_cat' );
|
||||
}
|
||||
if ( $do_check_by_product_tags ) {
|
||||
$_product_tags = wcj_get_the_terms( $product_id, 'product_tag' );
|
||||
}
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( $do_check_by_users ) {
|
||||
$users = get_option( 'wcj_currency_per_product_users_' . $i, '' );
|
||||
if ( ! empty( $users ) && in_array( $product_author_id, $users ) ) {
|
||||
return get_option( 'wcj_currency_per_product_currency_' . $i );
|
||||
}
|
||||
}
|
||||
if ( $do_check_by_user_roles ) {
|
||||
$user_roles = get_option( 'wcj_currency_per_product_user_roles_' . $i, '' );
|
||||
if ( ! empty( $user_roles ) && wcj_is_user_role( $user_roles, $product_author_id ) ) {
|
||||
return get_option( 'wcj_currency_per_product_currency_' . $i );
|
||||
}
|
||||
}
|
||||
if ( $do_check_by_product_cats ) {
|
||||
$product_cats = get_option( 'wcj_currency_per_product_product_cats_' . $i, '' );
|
||||
if ( ! empty( $_product_cats ) && ! empty( $product_cats ) ) {
|
||||
$_intersect = array_intersect( $_product_cats, $product_cats );
|
||||
if ( ! empty( $_intersect ) ) {
|
||||
return get_option( 'wcj_currency_per_product_currency_' . $i );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $do_check_by_product_tags ) {
|
||||
$product_tags = get_option( 'wcj_currency_per_product_product_tags_' . $i, '' );
|
||||
if ( ! empty( $_product_tags ) && ! empty( $product_tags ) ) {
|
||||
$_intersect = array_intersect( $_product_tags, $product_tags );
|
||||
if ( ! empty( $_intersect ) ) {
|
||||
return get_option( 'wcj_currency_per_product_currency_' . $i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// By product meta
|
||||
return ( $this->is_currency_per_product_by_product_enabled ? get_post_meta( $product_id, '_' . 'wcj_currency_per_product_currency', true ) : false );
|
||||
}
|
||||
|
||||
/**
|
||||
* validate_on_add_to_cart.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function validate_on_add_to_cart( $passed, $product_id ) {
|
||||
$cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
|
||||
if ( 'leave_one_product' === $cart_checkout_behaviour ) {
|
||||
foreach ( WC()->cart->get_cart() as $cart_item ) {
|
||||
if ( $cart_item['product_id'] != $product_id ) {
|
||||
wc_add_notice( get_option( 'wcj_currency_per_product_cart_checkout_leave_one_product',
|
||||
__( 'Only one product can be added to the cart. Clear the cart or finish the order, before adding another product to the cart.', 'woocommerce-jetpack' ) ), 'error' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} elseif ( 'leave_same_currency' === $cart_checkout_behaviour ) {
|
||||
$shop_currency = get_option( 'woocommerce_currency' );
|
||||
$product_currency = $this->get_product_currency( $product_id );
|
||||
if ( '' == $product_currency ) {
|
||||
$product_currency = $shop_currency;
|
||||
}
|
||||
foreach ( WC()->cart->get_cart() as $cart_item ) {
|
||||
$cart_product_currency = ( isset( $cart_item['wcj_currency_per_product'] ) && '' != $cart_item['wcj_currency_per_product'] ) ?
|
||||
$cart_item['wcj_currency_per_product'] : $shop_currency;
|
||||
if ( $cart_product_currency != $product_currency ) {
|
||||
wc_add_notice( get_option( 'wcj_currency_per_product_cart_checkout_leave_same_currency',
|
||||
__( 'Only products with same currency can be added to the cart. Clear the cart or finish the order, before adding products with another currency to the cart.', 'woocommerce-jetpack' ) ), 'error' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $passed;
|
||||
}
|
||||
|
||||
/**
|
||||
* grouped_price_html.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function grouped_price_html( $price_html, $_product ) {
|
||||
$child_prices = array();
|
||||
foreach ( $_product->get_children() as $child_id ) {
|
||||
$child_prices[ $child_id ] = get_post_meta( $child_id, '_price', true );
|
||||
}
|
||||
if ( ! empty( $child_prices ) ) {
|
||||
asort( $child_prices );
|
||||
$min_price = current( $child_prices );
|
||||
$min_price_id = key( $child_prices );
|
||||
end( $child_prices );
|
||||
$max_price = current( $child_prices );
|
||||
$max_price_id = key( $child_prices );
|
||||
$min_currency_per_product_currency = $this->get_product_currency( $min_price_id );
|
||||
$max_currency_per_product_currency = $this->get_product_currency( $max_price_id );
|
||||
} else {
|
||||
$min_price = '';
|
||||
$max_price = '';
|
||||
}
|
||||
|
||||
if ( $min_price ) {
|
||||
if ( $min_price == $max_price && $min_currency_per_product_currency === $max_currency_per_product_currency ) {
|
||||
$display_price = wc_price( wcj_get_product_display_price( $_product, $min_price, 1 ), array( 'currency' => $min_currency_per_product_currency ) );
|
||||
} else {
|
||||
$from = wc_price( wcj_get_product_display_price( $_product, $min_price, 1 ), array( 'currency' => $min_currency_per_product_currency ) );
|
||||
$to = wc_price( wcj_get_product_display_price( $_product, $max_price, 1 ), array( 'currency' => $max_currency_per_product_currency ) );
|
||||
$display_price = sprintf( _x( '%1$s–%2$s', 'Price range: from-to', 'woocommerce' ), $from, $to );
|
||||
}
|
||||
$new_price_html = $display_price . $_product->get_price_suffix();
|
||||
return $new_price_html;
|
||||
}
|
||||
|
||||
return $price_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_currency_exchange_rate.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function get_currency_exchange_rate( $currency_code ) {
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( $currency_code === get_option( 'wcj_currency_per_product_currency_' . $i ) ) {
|
||||
return ( 0 != ( $rate = get_option( 'wcj_currency_per_product_exchange_rate_' . $i, 1 ) ) ? ( 1 / $rate ) : 1 );
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_return_saved_converted_price.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function maybe_return_saved_converted_price( $_product, $_currency ) {
|
||||
if ( $this->do_save_converted_prices ) {
|
||||
$product_id = ( isset( $_product->wcj_currency_per_product_item_key ) ? $_product->wcj_currency_per_product_item_key : wcj_get_product_id( $_product ) );
|
||||
if ( isset( $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ] ) ) {
|
||||
return $this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_save_converted_price.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function maybe_save_converted_price( $price, $_product, $_currency ) {
|
||||
if ( $this->do_save_converted_prices ) {
|
||||
$product_id = ( isset( $_product->wcj_currency_per_product_item_key ) ? $_product->wcj_currency_per_product_item_key : wcj_get_product_id( $_product ) );
|
||||
$this->saved_product_prices[ $product_id ][ $_product->wcj_currency_per_product ][ $_currency ] = $price;
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function change_price( $price, $_product ) {
|
||||
if ( isset( $_product->wcj_currency_per_product ) ) {
|
||||
$cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
|
||||
switch ( $cart_checkout_behaviour ) {
|
||||
case 'leave_one_product':
|
||||
case 'leave_same_currency':
|
||||
return $price;
|
||||
case 'convert_first_product':
|
||||
case 'convert_last_product':
|
||||
$shop_currency = get_option( 'woocommerce_currency' );
|
||||
if ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $_currency != $shop_currency ) {
|
||||
if ( $_product->wcj_currency_per_product === $_currency ) {
|
||||
return $price;
|
||||
} else {
|
||||
if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $_currency ) ) ) {
|
||||
return $saved_price;
|
||||
}
|
||||
$exchange_rate_product = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
|
||||
$exchange_rate_cart_checkout = $this->get_currency_exchange_rate( $_currency );
|
||||
$exchange_rate = $exchange_rate_product / $exchange_rate_cart_checkout;
|
||||
return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $_currency );
|
||||
}
|
||||
} elseif ( $_product->wcj_currency_per_product === $shop_currency ) {
|
||||
return $price;
|
||||
} else {
|
||||
if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $shop_currency ) ) ) {
|
||||
return $saved_price;
|
||||
}
|
||||
$exchange_rate = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
|
||||
return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $shop_currency );
|
||||
}
|
||||
default: // case 'convert_shop_default':
|
||||
$shop_currency = get_option( 'woocommerce_currency' );
|
||||
if ( false !== ( $saved_price = $this->maybe_return_saved_converted_price( $_product, $shop_currency ) ) ) {
|
||||
return $saved_price;
|
||||
}
|
||||
$exchange_rate = $this->get_currency_exchange_rate( $_product->wcj_currency_per_product );
|
||||
return $this->maybe_save_converted_price( $price * $exchange_rate, $_product, $shop_currency );
|
||||
}
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_cart_item_from_session.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function get_cart_item_from_session( $item, $values, $key ) {
|
||||
if ( array_key_exists( 'wcj_currency_per_product', $values ) ) {
|
||||
$item['data']->wcj_currency_per_product = $values['wcj_currency_per_product'];
|
||||
if ( $this->do_save_converted_prices ) {
|
||||
$item['data']->wcj_currency_per_product_item_key = $key;
|
||||
}
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_cart_item_data.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
|
||||
$currency_per_product_currency = $this->get_product_currency( $product_id );
|
||||
if ( '' != $currency_per_product_currency ) {
|
||||
$cart_item_data['wcj_currency_per_product'] = $currency_per_product_currency;
|
||||
}
|
||||
return $cart_item_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_cart_item.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.5.2
|
||||
* @todo `wcj_currency_per_product_item_key` seems to be not working here
|
||||
*/
|
||||
function add_cart_item( $cart_item_data, $cart_item_key ) {
|
||||
if ( isset( $cart_item_data['wcj_currency_per_product'] ) ) {
|
||||
$cart_item_data['data']->wcj_currency_per_product = $cart_item_data['wcj_currency_per_product'];
|
||||
if ( $this->do_save_converted_prices ) {
|
||||
$cart_item_data['data']->wcj_currency_per_product_item_key = $cart_item_key;
|
||||
}
|
||||
}
|
||||
return $cart_item_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_current_product_id_and_currency.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function get_current_product_id_and_currency() {
|
||||
// Get ID
|
||||
$the_ID = false;
|
||||
global $product;
|
||||
if ( $product ) {
|
||||
$the_ID = wcj_get_product_id_or_variation_parent_id( $product );
|
||||
}
|
||||
if ( ! $the_ID && isset( $_REQUEST['product_id'] ) ) {
|
||||
$the_ID = $_REQUEST['product_id'];
|
||||
}
|
||||
if ( ! $the_ID && isset( $_POST['form'] ) ) { // WooCommerce Bookings plugin
|
||||
$posted = array();
|
||||
parse_str( $_POST['form'], $posted );
|
||||
$the_ID = isset( $posted['add-to-cart'] ) ? $posted['add-to-cart'] : 0;
|
||||
}
|
||||
if ( ! $the_ID && '' != ( $eventon_wc_product_id = get_post_meta( get_the_ID(), 'tx_woocommerce_product_id', true ) ) ) { // EventON plugin
|
||||
$the_ID = $eventon_wc_product_id;
|
||||
}
|
||||
if ( ! $the_ID ) {
|
||||
$the_ID = get_the_ID();
|
||||
}
|
||||
// Get currency
|
||||
if ( $the_ID && 'product' === get_post_type( $the_ID ) ) {
|
||||
$currency_per_product_currency = $this->get_product_currency( $the_ID );
|
||||
return ( '' != $currency_per_product_currency ) ? $currency_per_product_currency : false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_cart_checkout_currency.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function get_cart_checkout_currency() {
|
||||
$cart_checkout_behaviour = get_option( 'wcj_currency_per_product_cart_checkout', 'convert_shop_default' );
|
||||
if ( false !== ( $value = apply_filters( 'wcj_currency_per_product_cart_checkout_currency', false, $cart_checkout_behaviour ) ) ) {
|
||||
return $value;
|
||||
}
|
||||
/*
|
||||
* `wcj_currency_per_product_cart_checkout_currency` filter example:
|
||||
*
|
||||
* if ( function_exists( 'YITH_Request_Quote' ) && isset( YITH_Request_Quote()->raq_content ) ) {
|
||||
* foreach ( YITH_Request_Quote()->raq_content as $raq_product ) {
|
||||
* if ( isset( $raq_product['product_id'] ) ) {
|
||||
* return get_post_meta( $raq_product['product_id'], '_' . 'wcj_currency_per_product_currency', true );
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
*/
|
||||
if ( ! isset( WC()->cart ) || WC()->cart->is_empty() ) {
|
||||
return false;
|
||||
}
|
||||
if ( 'convert_shop_default' === $cart_checkout_behaviour ) {
|
||||
return false;
|
||||
}
|
||||
$cart_items = WC()->cart->get_cart();
|
||||
if ( 'convert_last_product' === $cart_checkout_behaviour ) {
|
||||
$cart_items = array_reverse( $cart_items );
|
||||
}
|
||||
foreach ( $cart_items as $cart_item ) {
|
||||
return ( isset( $cart_item['wcj_currency_per_product'] ) ) ? $cart_item['wcj_currency_per_product'] : false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* is_cart_or_checkout_or_ajax.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.7.0
|
||||
* @todo fix AJAX issue (for minicart)
|
||||
*/
|
||||
function is_cart_or_checkout_or_ajax() {
|
||||
return apply_filters( 'wcj_currency_per_product_is_cart_or_checkout',
|
||||
( ( function_exists( 'is_cart' ) && is_cart() ) || ( function_exists( 'is_checkout' ) && is_checkout() ) /* || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) */ ) );
|
||||
/*
|
||||
* `wcj_currency_per_product_is_cart_or_checkout` filter example:
|
||||
*
|
||||
* if ( function_exists( 'YITH_Request_Quote' ) && 0 != ( $raq_page_id = YITH_Request_Quote()->get_raq_page_id() ) && $raq_page_id == get_the_ID() ) {
|
||||
* return true;
|
||||
* }
|
||||
*
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* change_currency_code.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function change_currency_code( $currency ) {
|
||||
if ( false != ( $_currency = $this->get_current_product_id_and_currency() ) ) {
|
||||
return $_currency;
|
||||
} elseif ( $this->is_cart_or_checkout_or_ajax() ) {
|
||||
return ( false != ( $_currency = $this->get_cart_checkout_currency() ) ) ? $_currency : $currency;
|
||||
}
|
||||
return $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_currency_symbol.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.5.2
|
||||
* @todo check do we really need this function? isn't `change_currency_code()` enough?
|
||||
*/
|
||||
function change_currency_symbol( $currency_symbol, $currency ) {
|
||||
if ( false != ( $_currency = $this->get_current_product_id_and_currency() ) ) {
|
||||
if ( $currency === $_currency ) {
|
||||
return wcj_get_currency_symbol( $_currency );
|
||||
}
|
||||
} elseif ( $this->is_cart_or_checkout_or_ajax() ) {
|
||||
return ( false != ( $_currency = $this->get_cart_checkout_currency() ) && $currency === $_currency ) ? wcj_get_currency_symbol( $_currency ) : $currency_symbol;
|
||||
}
|
||||
return $currency_symbol;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Currency_Per_Product();
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Custom CSS
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.7.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Custom_CSS' ) ) :
|
||||
|
||||
class WCJ_Custom_CSS extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.7.0
|
||||
* @todo wp_safe_redirect after saving settings
|
||||
* @todo automatically enable the module if v <= 2.6.0 and General module enabled and `wcj_general_custom_css` or `wcj_general_custom_admin_css` are not empty
|
||||
* @todo (maybe) set `add_action` `priority` to `PHP_INT_MAX`
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'custom_css';
|
||||
$this->short_desc = __( 'Custom CSS', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Separate custom CSS for front and back end. Per product CSS.', 'woocommerce-jetpack' );
|
||||
// $this->desc = __( 'Another custom CSS, if you need one.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-booster-custom-css';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// Frontend
|
||||
if ( '' != get_option( 'wcj_general_custom_css', '' ) ) {
|
||||
add_action( 'wp_head', array( $this, 'hook_custom_css' ) );
|
||||
}
|
||||
// Admin
|
||||
if ( '' != get_option( 'wcj_general_custom_admin_css', '' ) ) {
|
||||
add_action( 'admin_head', array( $this, 'hook_custom_admin_css' ) );
|
||||
}
|
||||
// Per product
|
||||
if ( 'yes' === get_option( 'wcj_custom_css_per_product', 'no' ) ) {
|
||||
add_action( 'wp_head', array( $this, 'maybe_add_per_product_css' ) );
|
||||
// Settings
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_per_product_css.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function maybe_add_per_product_css() {
|
||||
$post_id = get_the_ID();
|
||||
if ( $post_id > 0 && 'yes' === get_post_meta( $post_id, '_' . 'wcj_product_css_enabled', true ) ) {
|
||||
if ( '' != ( $css = get_post_meta( $post_id, '_' . 'wcj_product_css', true ) ) ) {
|
||||
echo '<style>' . $css . '</style>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hook_custom_css.
|
||||
*
|
||||
* @version 2.7.0
|
||||
*/
|
||||
function hook_custom_css() {
|
||||
echo '<style>' . get_option( 'wcj_general_custom_css', '' ) . '</style>';
|
||||
}
|
||||
|
||||
/**
|
||||
* hook_custom_admin_css.
|
||||
*
|
||||
* @version 2.7.0
|
||||
*/
|
||||
function hook_custom_admin_css() {
|
||||
echo '<style>' . get_option( 'wcj_general_custom_admin_css', '' ) . '</style>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Custom_CSS();
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Custom JS
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @since 2.8.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Custom_JS' ) ) :
|
||||
|
||||
class WCJ_Custom_JS extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
* @todo footer or head
|
||||
* @todo (maybe) wp_safe_redirect after saving settings
|
||||
* @todo (maybe) set `add_action` `priority` to `PHP_INT_MAX`
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'custom_js';
|
||||
$this->short_desc = __( 'Custom JS', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Separate custom JS for front and back end.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-booster-custom-js';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( '' != get_option( 'wcj_custom_js_frontend', '' ) ) {
|
||||
add_action( 'wp_head', array( $this, 'custom_frontend_js' ) );
|
||||
}
|
||||
if ( '' != get_option( 'wcj_custom_js_backend', '' ) ) {
|
||||
add_action( 'admin_head', array( $this, 'custom_backend_js' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* custom_frontend_js.
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function custom_frontend_js() {
|
||||
echo '<script>' . do_shortcode( get_option( 'wcj_custom_js_frontend', '' ) ) . '</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* custom_backend_js.
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function custom_backend_js() {
|
||||
echo '<script>' . do_shortcode( get_option( 'wcj_custom_js_backend', '' ) ) . '</script>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Custom_JS();
|
||||
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Email Options
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.9.1
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Email_Options' ) ) :
|
||||
|
||||
class WCJ_Email_Options extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.9.1
|
||||
* @todo meta customizer - check "gravity-forms-emails-woocommerce" plugin
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'email_options';
|
||||
$this->short_desc = __( 'Email Options', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'WooCommerce email options. E.g.: add another email recipient(s) to all WooCommerce emails.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-email-options';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// Email Forwarding
|
||||
if ( '' != get_option( 'wcj_emails_bcc_email', '' ) ) {
|
||||
add_filter( 'woocommerce_email_headers', array( $this, 'add_bcc_email' ), PHP_INT_MAX, 3 );
|
||||
}
|
||||
if ( '' != get_option( 'wcj_emails_cc_email', '' ) ) {
|
||||
add_filter( 'woocommerce_email_headers', array( $this, 'add_cc_email' ), PHP_INT_MAX, 3 );
|
||||
}
|
||||
// Product Info
|
||||
if ( 'yes' === get_option( 'wcj_product_info_in_email_order_item_name_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_order_item_name', array( $this, 'add_product_info_to_email_order_item_name' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
// Settings
|
||||
add_filter( 'woocommerce_email_settings', array( $this, 'add_email_forwarding_fields_to_wc_standard_settings' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_product_info_to_email_order_item_name.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function add_product_info_to_email_order_item_name( $item_name, $item ) {
|
||||
if ( $item['product_id'] ) {
|
||||
global $post;
|
||||
$product_id = ( ! empty( $item['variation_id'] ) ? $item['variation_id'] : $item['product_id'] );
|
||||
$post = get_post( $product_id );
|
||||
setup_postdata( $post );
|
||||
$item_name .= do_shortcode( get_option( 'wcj_product_info_in_email_order_item_name', '[wcj_product_categories strip_tags="yes" before="<hr><em>" after="</em>"]' ) );
|
||||
wp_reset_postdata();
|
||||
}
|
||||
return $item_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_check_order_status.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function maybe_check_order_status( $_object ) {
|
||||
$enable_order_statuses = apply_filters( 'booster_option', '', get_option( 'wcj_emails_forwarding_enable_order_status', '' ) );
|
||||
if ( ! empty( $enable_order_statuses ) && isset( $_object ) && is_object( $_object ) && 'WC_Order' === get_class( $_object ) ) {
|
||||
if ( ! in_array( $_object->get_status(), $enable_order_statuses ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add another email recipient to all WooCommerce emails.
|
||||
*
|
||||
* @version 3.5.0
|
||||
*/
|
||||
function add_bcc_email( $email_headers, $id, $_object ) {
|
||||
return ( $this->maybe_check_order_status( $_object ) ? $email_headers . "Bcc: " . get_option( 'wcj_emails_bcc_email', '' ) . "\r\n" : $email_headers );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add another email recipient to all WooCommerce emails.
|
||||
*
|
||||
* @version 3.5.0
|
||||
*/
|
||||
function add_cc_email( $email_headers, $id, $_object ) {
|
||||
return ( $this->maybe_check_order_status( $_object ) ? $email_headers . "Cc: " . get_option( 'wcj_emails_cc_email', '' ) . "\r\n" : $email_headers );
|
||||
}
|
||||
|
||||
/**
|
||||
* get_emails_forwarding_settings.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.3.9
|
||||
*/
|
||||
function get_emails_forwarding_settings( $extended_title = false ) {
|
||||
return array(
|
||||
array(
|
||||
'title' => ( $extended_title ) ?
|
||||
__( 'Booster: Email Forwarding Options', 'woocommerce-jetpack' ) :
|
||||
__( 'Email Forwarding Options', 'woocommerce-jetpack' ),
|
||||
'type' => 'title',
|
||||
'desc' => __( 'This section lets you add another email recipient(s) to all WooCommerce emails. Leave blank to disable.', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_emails_forwarding_options',
|
||||
),
|
||||
array(
|
||||
'title' => __( 'Cc Email', 'woocommerce-jetpack' ),
|
||||
'desc_tip' => __( 'Cc to email, e.g. youremail@yourdomain.com. Leave blank to disable.', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_emails_cc_email',
|
||||
'default' => '',
|
||||
'type' => 'text',
|
||||
),
|
||||
array(
|
||||
'title' => __( 'Bcc Email', 'woocommerce-jetpack' ),
|
||||
'desc_tip' => __( 'Bcc to email, e.g. youremail@yourdomain.com. Leave blank to disable.', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_emails_bcc_email',
|
||||
'default' => '',
|
||||
'type' => 'text',
|
||||
),
|
||||
array(
|
||||
'title' => __( 'Orders Emails: Enable for Statuses', 'woocommerce-jetpack' ),
|
||||
'desc' => apply_filters( 'booster_message', '', 'desc' ),
|
||||
'desc_tip' => __( 'If you want to forward emails for certain orders only, set order statuses here. Leave blank to send for all orders statuses.', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_emails_forwarding_enable_order_status',
|
||||
'default' => '',
|
||||
'type' => 'multiselect',
|
||||
'class' => 'chosen_select',
|
||||
'options' => wcj_get_order_statuses(),
|
||||
'custom_attributes' => apply_filters( 'booster_message', '', 'disabled' ),
|
||||
),
|
||||
array(
|
||||
'type' => 'sectionend',
|
||||
'id' => 'wcj_emails_forwarding_options',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* add_email_forwarding_fields_to_wc_standard_settings.
|
||||
*
|
||||
* @version 2.3.9
|
||||
* @todo (maybe) remove this completely (and then move `get_emails_forwarding_settings()` to settings file)
|
||||
*/
|
||||
function add_email_forwarding_fields_to_wc_standard_settings( $settings ) {
|
||||
$updated_settings = array();
|
||||
foreach ( $settings as $section ) {
|
||||
if ( isset( $section['id'] ) && 'email_template_options' == $section['id'] && isset( $section['type'] ) && 'title' == $section['type'] ) {
|
||||
$updated_settings = array_merge( $updated_settings, $this->get_emails_forwarding_settings( true ) );
|
||||
}
|
||||
$updated_settings[] = $section;
|
||||
}
|
||||
return $updated_settings;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Email_Options();
|
||||
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Email Verification
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.8.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Email_Verification' ) ) :
|
||||
|
||||
class WCJ_Email_Verification extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'emails_verification';
|
||||
$this->short_desc = __( 'Email Verification', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add WooCommerce email verification.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-email-verification';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'init', array( $this, 'process_email_verification' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_registration_redirect', array( $this, 'prevent_user_login_automatically_after_register' ), PHP_INT_MAX );
|
||||
add_filter( 'wp_authenticate_user', array( $this, 'check_if_user_email_is_verified' ), PHP_INT_MAX );
|
||||
add_action( 'user_register', array( $this, 'reset_and_mail_activation_link' ), PHP_INT_MAX );
|
||||
add_filter( 'manage_users_columns', array( $this, 'add_verified_email_column' ) );
|
||||
add_filter( 'manage_users_custom_column', array( $this, 'render_verified_email_column' ), 10, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_verified_email_column.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
* @todo (maybe) add option to enable/disable the column
|
||||
*/
|
||||
function add_verified_email_column( $columns ) {
|
||||
$columns['wcj_is_verified_email'] = __( 'Verified', 'woocommerce-jetpack' );
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* render_verified_email_column.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function render_verified_email_column( $output, $column_name, $user_id ) {
|
||||
if ( 'wcj_is_verified_email' === $column_name ) {
|
||||
$replaced_values = array(
|
||||
'1' => '<span title="' . __( 'Email verified', 'woocommerce-jetpack' ) . '">☑</span>',
|
||||
'0' => '<span title="' . __( 'Email not verified', 'woocommerce-jetpack' ) . '">✖</span>',
|
||||
);
|
||||
return str_replace( array_keys( $replaced_values ), array_values( $replaced_values ), get_user_meta( $user_id, 'wcj_is_activated', true ) );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* prevent_user_login_automatically_after_register.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function prevent_user_login_automatically_after_register( $redirect_to ) {
|
||||
wp_logout();
|
||||
return add_query_arg( 'wcj_activate_account_message', '', $redirect_to );
|
||||
}
|
||||
|
||||
/**
|
||||
* check_if_user_email_is_verified.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function check_if_user_email_is_verified( $userdata ) {
|
||||
if (
|
||||
( 'yes' === get_option( 'wcj_emails_verification_already_registered_enabled', 'no' ) && ! get_user_meta( $userdata->ID, 'wcj_is_activated', true ) ) ||
|
||||
( 'no' === get_option( 'wcj_emails_verification_already_registered_enabled', 'no' ) && '0' === get_user_meta( $userdata->ID, 'wcj_is_activated', true ) )
|
||||
) {
|
||||
if ( isset( $userdata->roles ) && ! empty( $userdata->roles ) ) {
|
||||
$userdata_roles = wcj_get_array( $userdata->roles );
|
||||
$skip_user_roles = wcj_get_array( get_option( 'wcj_emails_verification_skip_user_roles', array( 'administrator' ) ) );
|
||||
$_intersect = array_intersect( $userdata_roles, $skip_user_roles );
|
||||
if ( ! empty( $_intersect ) ) {
|
||||
return $userdata;
|
||||
}
|
||||
}
|
||||
$error_message = do_shortcode( get_option( 'wcj_emails_verification_error_message',
|
||||
__( 'Your account has to be activated before you can login. You can resend email with verification link by clicking <a href="%resend_verification_url%">here</a>.', 'woocommerce-jetpack' )
|
||||
) );
|
||||
$error_message = str_replace( '%resend_verification_url%', add_query_arg( 'wcj_user_id', $userdata->ID, wc_get_page_permalink( 'myaccount' ) ), $error_message );
|
||||
$userdata = new WP_Error( 'booster_email_verified_error', $error_message );
|
||||
}
|
||||
return $userdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* reset_and_mail_activation_link.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.8.0
|
||||
* @todo %site_name% etc. in `wcj_emails_verification_email_subject`
|
||||
* @todo ticket #5373 - unexpected issue with "Activation failed, please contact our administrator" message
|
||||
*/
|
||||
function reset_and_mail_activation_link( $user_id ) {
|
||||
$user_info = get_userdata( $user_id );
|
||||
$code = md5( time() );
|
||||
$url = add_query_arg( 'wcj_verify_email', base64_encode( json_encode( array( 'id' => $user_id, 'code' => $code ) ) ), wc_get_page_permalink( 'myaccount' ) );
|
||||
$email_content = do_shortcode( apply_filters( 'booster_option',
|
||||
__( 'Please click the following link to verify your email:<br><br><a href="%verification_url%">%verification_url%</a>', 'woocommerce-jetpack' ),
|
||||
get_option( 'wcj_emails_verification_email_content',
|
||||
__( 'Please click the following link to verify your email:<br><br><a href="%verification_url%">%verification_url%</a>', 'woocommerce-jetpack' ) ) ) );
|
||||
$email_content = str_replace( '%verification_url%', $url, $email_content );
|
||||
$email_subject = do_shortcode( apply_filters( 'booster_option',
|
||||
__( 'Please activate your account', 'woocommerce-jetpack' ),
|
||||
get_option( 'wcj_emails_verification_email_subject',
|
||||
__( 'Please activate your account', 'woocommerce-jetpack' ) ) ) );
|
||||
update_user_meta( $user_id, 'wcj_is_activated', '0' );
|
||||
update_user_meta( $user_id, 'wcj_activation_code', $code );
|
||||
if ( 'wc' === apply_filters( 'booster_option', 'plain', get_option( 'wcj_emails_verification_email_template', 'plain' ) ) ) {
|
||||
$email_content = wcj_wrap_in_wc_email_template( $email_content,
|
||||
get_option( 'wcj_emails_verification_email_template_wc_heading', __( 'Activate your account', 'woocommerce-jetpack' ) ) );
|
||||
}
|
||||
wc_mail( $user_info->user_email, $email_subject, $email_content );
|
||||
}
|
||||
|
||||
/**
|
||||
* process_email_verification.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function process_email_verification() {
|
||||
if ( isset( $_GET['wcj_verify_email'] ) ) {
|
||||
$data = json_decode( base64_decode( $_GET['wcj_verify_email'] ), true );
|
||||
if ( get_user_meta( $data['id'], 'wcj_activation_code', true ) == $data['code'] ) {
|
||||
update_user_meta( $data['id'], 'wcj_is_activated', '1' );
|
||||
wc_add_notice( do_shortcode( get_option( 'wcj_emails_verification_success_message',
|
||||
__( '<strong>Success:</strong> Your account has been activated!', 'woocommerce-jetpack' ) ) ) );
|
||||
if ( 'yes' === get_option( 'wcj_emails_verification_redirect_on_success', 'yes' ) ) {
|
||||
wp_set_current_user( $data['id'] );
|
||||
wp_set_auth_cookie( $data['id'] );
|
||||
header( wc_get_page_permalink( 'myaccount' ) );
|
||||
}
|
||||
} else {
|
||||
$_notice = do_shortcode(
|
||||
get_option( 'wcj_emails_verification_failed_message',
|
||||
__( '<strong>Error:</strong> Activation failed, please contact our administrator. You can resend email with verification link by clicking <a href="%resend_verification_url%">here</a>.', 'woocommerce-jetpack' )
|
||||
)
|
||||
);
|
||||
$_notice = str_replace( '%resend_verification_url%', add_query_arg( 'wcj_user_id', $data['id'], wc_get_page_permalink( 'myaccount' ) ), $_notice );
|
||||
wc_add_notice( $_notice, 'error' );
|
||||
}
|
||||
}
|
||||
if ( isset( $_GET['wcj_activate_account_message'] ) ) {
|
||||
wc_add_notice( do_shortcode( get_option( 'wcj_emails_verification_activation_message',
|
||||
__( 'Thank you for your registration. Your account has to be activated before you can login. Please check your email.', 'woocommerce-jetpack' ) ) ) );
|
||||
}
|
||||
if ( isset( $_GET['wcj_user_id'] ) ) {
|
||||
$this->reset_and_mail_activation_link( $_GET['wcj_user_id'] );
|
||||
wc_add_notice( do_shortcode( get_option( 'wcj_emails_verification_email_resend_message',
|
||||
__( '<strong>Success:</strong> Your activation email has been resend. Please check your email.', 'woocommerce-jetpack' ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Email_Verification();
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Custom Emails
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Emails' ) ) :
|
||||
|
||||
class WCJ_Emails extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'emails';
|
||||
$this->short_desc = __( 'Custom Emails', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add custom emails to WooCommerce.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-custom-emails';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_email_actions', array( $this, 'add_custom_woocommerce_email_actions' ) );
|
||||
add_filter( 'woocommerce_email_classes', array( $this, 'add_custom_emails_to_wc' ) );
|
||||
add_filter( 'woocommerce_resend_order_emails_available', array( $this, 'add_custom_emails_to_wc_resend_order_emails' ) );
|
||||
if ( ! WCJ_IS_WC_VERSION_BELOW_3_2_0 ) {
|
||||
add_filter( 'woocommerce_order_actions', array( $this, 'add_custom_emails_order_actions' ), PHP_INT_MAX, 1 );
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
|
||||
add_action( 'woocommerce_order_action_' . 'wcj_send_email_custom' . '_' . $i,
|
||||
array( $this, 'do_custom_emails_order_actions' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* do_custom_emails_order_actions.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 3.2.0
|
||||
*/
|
||||
function do_custom_emails_order_actions( $order ) {
|
||||
$booster_action_prefix = 'woocommerce_order_action_' . 'wcj_send_email_custom' . '_';
|
||||
$_current_filter = current_filter();
|
||||
if ( substr( $_current_filter, 0, strlen( $booster_action_prefix ) ) === $booster_action_prefix ) {
|
||||
$email_nr = substr( $_current_filter, strlen( $booster_action_prefix ) );
|
||||
WC()->payment_gateways();
|
||||
WC()->shipping();
|
||||
WC()->mailer()->emails[ 'WC_Email_WCJ_Custom_' . $email_nr ]->trigger( $order->get_id(), $order );
|
||||
$order->add_order_note(
|
||||
sprintf( __( 'Booster: Emails: %s manually sent.', 'woocommerce-jetpack' ),
|
||||
get_option( 'wcj_emails_custom_emails_admin_title_' . $email_nr, __( 'Custom', 'woocommerce-jetpack' ) . ' #' . $email_nr ) ),
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_emails_order_actions.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 3.2.0
|
||||
* @todo (maybe) add "Add Custom Email(s) to Order Actions" option (in WC >= 3.2.0); same to `woocommerce_order_action_`
|
||||
*/
|
||||
function add_custom_emails_order_actions( $actions ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
|
||||
$actions[ 'wcj_send_email_custom' . '_' . $i ] = sprintf( apply_filters( 'wcj_emails_custom_emails_order_action_text',
|
||||
__( 'Booster: Send Email: %s', 'woocommerce-jetpack' ), $i ),
|
||||
get_option( 'wcj_emails_custom_emails_admin_title_' . $i, __( 'Custom', 'woocommerce-jetpack' ) . ' #' . $i )
|
||||
);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_woocommerce_email_actions.
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @since 2.4.5
|
||||
*/
|
||||
function add_custom_woocommerce_email_actions( $email_actions ) {
|
||||
$email_actions[] = 'woocommerce_checkout_order_processed';
|
||||
$order_statuses = wcj_get_order_statuses();
|
||||
foreach ( $order_statuses as $slug => $name ) {
|
||||
$email_actions[] = 'woocommerce_order_status_' . $slug;
|
||||
foreach ( $order_statuses as $slug2 => $name2 ) {
|
||||
if ( $slug != $slug2 ) {
|
||||
$email_actions[] = 'woocommerce_order_status_' . $slug . '_to_' . $slug2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $email_actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_emails_to_wc_resend_order_emails.
|
||||
*
|
||||
* @version 2.3.9
|
||||
* @since 2.3.9
|
||||
*/
|
||||
function add_custom_emails_to_wc_resend_order_emails( $emails ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
|
||||
$emails[] = 'wcj_custom' . '_' . $i;
|
||||
}
|
||||
return $emails;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_emails_to_wc.
|
||||
*
|
||||
* @version 2.3.9
|
||||
* @since 2.3.9
|
||||
*/
|
||||
function add_custom_emails_to_wc( $emails ) {
|
||||
if ( ! class_exists( 'WC_Email_WCJ_Custom' ) ) {
|
||||
require_once( 'emails/class-wc-email-wcj-custom.php' );
|
||||
}
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_emails_custom_emails_total_number', 1 ) ); $i++ ) {
|
||||
$emails[ 'WC_Email_WCJ_Custom_' . $i ] = new WC_Email_WCJ_Custom( $i );
|
||||
}
|
||||
return $emails;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Emails();
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Empty Cart Button
|
||||
*
|
||||
* @version 3.5.3
|
||||
* @since 2.2.1
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Empty_Cart_Button' ) ) :
|
||||
|
||||
class WCJ_Empty_Cart_Button extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.5.3
|
||||
* @since 2.2.1
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'empty_cart';
|
||||
$this->short_desc = __( 'Empty Cart Button', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add (and customize) "Empty Cart" button to the cart and checkout pages.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-empty-cart-button';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'init', array( $this, 'maybe_empty_cart' ) );
|
||||
if ( 'disable' != ( $empty_cart_cart_position = apply_filters( 'booster_option', 'woocommerce_after_cart',
|
||||
get_option( 'wcj_empty_cart_position', 'woocommerce_after_cart' ) ) )
|
||||
) {
|
||||
add_action( $empty_cart_cart_position, array( $this, 'add_empty_cart_link' ) );
|
||||
}
|
||||
if ( 'disable' != ( $empty_cart_checkout_position = get_option( 'wcj_empty_cart_checkout_position', 'disable' ) ) ) {
|
||||
$deprecated_hooks = array(
|
||||
'woocommerce_checkout_before_customer_details' => 'woocommerce_before_checkout_form',
|
||||
'woocommerce_checkout_billing' => 'woocommerce_before_checkout_form',
|
||||
'woocommerce_checkout_shipping' => 'woocommerce_before_checkout_form',
|
||||
'woocommerce_checkout_after_customer_details' => 'woocommerce_after_checkout_form',
|
||||
'woocommerce_checkout_before_order_review' => 'woocommerce_after_checkout_form',
|
||||
'woocommerce_checkout_order_review' => 'woocommerce_after_checkout_form',
|
||||
'woocommerce_checkout_after_order_review' => 'woocommerce_after_checkout_form',
|
||||
);
|
||||
if ( isset( $deprecated_hooks[ $empty_cart_checkout_position ] ) ) {
|
||||
$empty_cart_checkout_position = $deprecated_hooks[ $empty_cart_checkout_position ];
|
||||
update_option( 'wcj_empty_cart_checkout_position', $empty_cart_checkout_position );
|
||||
}
|
||||
add_action( $empty_cart_checkout_position, array( $this, 'add_empty_cart_link' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_empty_cart_link.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function add_empty_cart_link() {
|
||||
echo wcj_empty_cart_button_html();
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_empty_cart.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function maybe_empty_cart() {
|
||||
if ( isset( $_POST['wcj_empty_cart'] ) && isset( WC()->cart ) ) {
|
||||
WC()->cart->empty_cart();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Empty_Cart_Button();
|
||||
@@ -0,0 +1,506 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - EU VAT Number
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.3.9
|
||||
* @author Algoritmika Ltd.
|
||||
* @todo clean up
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_EU_VAT_Number' ) ) :
|
||||
|
||||
class WCJ_EU_VAT_Number extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.3.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'eu_vat_number';
|
||||
$this->short_desc = __( 'EU VAT Number', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Collect and validate EU VAT numbers on the checkout. Automatically disable VAT for valid numbers. Add all EU countries VAT standard rates to WooCommerce.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-eu-vat-number';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'eu_countries_vat_rates' => array(
|
||||
'title' => __( 'EU Countries VAT Rates', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Add all EU countries VAT standard rates to WooCommerce.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'init', array( $this, 'start_session' ) );
|
||||
add_filter( 'woocommerce_checkout_fields', array( $this, 'add_eu_vat_number_checkout_field_to_frontend' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_admin_billing_fields', array( $this, 'add_billing_eu_vat_number_field_to_admin_order_display' ), PHP_INT_MAX );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'wp_ajax_wcj_validate_eu_vat_number', array( $this, 'wcj_validate_eu_vat_number' ) );
|
||||
add_action( 'wp_ajax_nopriv_wcj_validate_eu_vat_number', array( $this, 'wcj_validate_eu_vat_number' ) );
|
||||
// add_filter( 'woocommerce_form_field_text', array( $this, 'add_eu_vat_verify_button' ), PHP_INT_MAX, 4 );
|
||||
// add_action( 'init', array( $this, 'wcj_validate_eu_vat_number' ) );
|
||||
// add_filter( 'woocommerce_find_rates', array( $this, 'maybe_exclude_vat' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'init', array( $this, 'maybe_exclude_vat' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_after_checkout_validation', array( $this, 'checkout_validate_vat' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_customer_meta_fields', array( $this, 'add_eu_vat_number_customer_meta_field' ) );
|
||||
add_filter( 'default_checkout_billing_eu_vat_number', array( $this, 'add_default_checkout_billing_eu_vat_number' ), PHP_INT_MAX, 2 );
|
||||
|
||||
if ( 'after_order_table' === get_option( 'wcj_eu_vat_number_display_position', 'after_order_table' ) ) {
|
||||
add_action( 'woocommerce_order_details_after_order_table', array( $this, 'add_eu_vat_number_to_order_display' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_email_after_order_table', array( $this, 'add_eu_vat_number_to_order_display' ), PHP_INT_MAX );
|
||||
} else {
|
||||
add_filter( 'woocommerce_order_formatted_billing_address', array( $this, 'add_eu_vat_number_to_order_billing_address' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_my_account_my_address_formatted_address', array( $this, 'add_eu_vat_number_to_my_account_billing_address' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_localisation_address_formats', array( $this, 'add_eu_vat_number_to_address_formats' ) );
|
||||
add_filter( 'woocommerce_formatted_address_replacements', array( $this, 'replace_eu_vat_number_in_address_formats' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
$this->eu_countries_vat_rates_tool = include_once( 'tools/class-wcj-eu-countries-vat-rates-tool.php' );
|
||||
|
||||
// EU VAT number summary on order edit page
|
||||
if ( 'yes' === get_option( 'wcj_eu_vat_number_add_order_edit_metabox', 'no' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
// "Validate VAT and remove taxes" button
|
||||
add_action( 'admin_init', array( $this, 'admin_validate_vat_and_maybe_remove_taxes' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Admin order edit - "Load billing address" button
|
||||
add_filter( 'woocommerce_ajax_get_customer_details', array( $this, 'add_billing_eu_vat_number_to_ajax_get_customer_details' ), PHP_INT_MAX, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* admin_validate_vat_and_maybe_remove_taxes.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function admin_validate_vat_and_maybe_remove_taxes() {
|
||||
if ( isset( $_GET['validate_vat_and_maybe_remove_taxes'] ) ) {
|
||||
$order_id = $_GET['validate_vat_and_maybe_remove_taxes'];
|
||||
$order = wc_get_order( $order_id );
|
||||
if ( $order ) {
|
||||
$vat_id = get_post_meta( $order_id, '_billing_eu_vat_number', true );
|
||||
if ( '' != $vat_id && strlen( $vat_id ) > 2 ) {
|
||||
if ( wcj_validate_vat( substr( $vat_id, 0, 2 ), substr( $vat_id, 2 ) ) ) {
|
||||
foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $item_id => $item ) {
|
||||
$item->set_taxes( false );
|
||||
}
|
||||
foreach ( $order->get_shipping_methods() as $item_id => $item ) {
|
||||
$item->set_taxes( false );
|
||||
}
|
||||
$order->update_taxes();
|
||||
$order->calculate_totals( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
wp_safe_redirect( remove_query_arg( 'validate_vat_and_maybe_remove_taxes' ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_billing_eu_vat_number_to_ajax_get_customer_details.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function add_billing_eu_vat_number_to_ajax_get_customer_details( $data, $customer, $user_id ) {
|
||||
$data['billing']['eu_vat_number'] = get_user_meta( $user_id, 'billing_eu_vat_number', true );
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_meta_box.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function add_meta_box() {
|
||||
$screen = ( isset( $this->meta_box_screen ) ) ? $this->meta_box_screen : 'shop_order';
|
||||
$context = ( isset( $this->meta_box_context ) ) ? $this->meta_box_context : 'side';
|
||||
$priority = ( isset( $this->meta_box_priority ) ) ? $this->meta_box_priority : 'low';
|
||||
add_meta_box(
|
||||
'wc-jetpack-' . $this->id,
|
||||
__( 'Booster', 'woocommerce-jetpack' ) . ': ' . $this->short_desc,
|
||||
array( $this, 'create_meta_box' ),
|
||||
$screen,
|
||||
$context,
|
||||
$priority
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_meta_box.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function create_meta_box() {
|
||||
$order_id = get_the_ID();
|
||||
$_order = wc_get_order( $order_id );
|
||||
$_customer_ip_address = ( WCJ_IS_WC_VERSION_BELOW_3 ? $_order->customer_ip_address : $_order->get_customer_ip_address() );
|
||||
|
||||
// Country by IP
|
||||
if ( class_exists( 'WC_Geolocation' ) ) {
|
||||
// Get the country by IP
|
||||
$location = WC_Geolocation::geolocate_ip( $_customer_ip_address );
|
||||
// Base fallback
|
||||
if ( empty( $location['country'] ) ) {
|
||||
$location = wc_format_country_state_string( apply_filters( 'woocommerce_customer_default_location', get_option( 'woocommerce_default_country' ) ) );
|
||||
}
|
||||
$customer_country = ( isset( $location['country'] ) ) ? $location['country'] : '';
|
||||
} else {
|
||||
$customer_country = '';
|
||||
}
|
||||
|
||||
// Customer EU VAT number
|
||||
$customer_eu_vat_number = get_post_meta( $order_id, '_billing_eu_vat_number', true );
|
||||
if ( '' == $customer_eu_vat_number ) {
|
||||
$customer_eu_vat_number = '-';
|
||||
}
|
||||
|
||||
// Taxes
|
||||
$taxes = '';
|
||||
$taxes_array = $_order->get_tax_totals();
|
||||
if ( empty( $taxes_array ) ) {
|
||||
$taxes = '-';
|
||||
} else {
|
||||
foreach ( $taxes_array as $tax ) {
|
||||
$taxes .= $tax->label . ': ' . $tax->formatted_amount . '<br>';
|
||||
}
|
||||
}
|
||||
|
||||
// Results table
|
||||
$table_data = array(
|
||||
array(
|
||||
__( 'Customer IP', 'woocommerce-jetpack' ),
|
||||
$_customer_ip_address
|
||||
),
|
||||
array(
|
||||
__( 'Country by IP', 'woocommerce-jetpack' ),
|
||||
wcj_get_country_flag_by_code( $customer_country ) . ' ' . wcj_get_country_name_by_code( $customer_country ) . ' [' . $customer_country . ']'
|
||||
),
|
||||
array(
|
||||
__( 'Customer EU VAT Number', 'woocommerce-jetpack' ),
|
||||
$customer_eu_vat_number
|
||||
),
|
||||
array(
|
||||
__( 'Taxes', 'woocommerce-jetpack' ),
|
||||
$taxes,
|
||||
),
|
||||
/* array(
|
||||
__( 'Customer Meta', 'woocommerce-jetpack' ),
|
||||
// '<pre>' . print_r( get_user_meta( $_order->customer_user ), true ). '</pre>',
|
||||
'<pre>' . print_r( get_user_by( 'ID', $_order->customer_user ), true ). '</pre>',
|
||||
), */
|
||||
);
|
||||
echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'vertical' ) );
|
||||
echo '<p>' . '<a href="' . add_query_arg( 'validate_vat_and_maybe_remove_taxes', $order_id ) . '">' .
|
||||
__( 'Validate VAT and remove taxes', 'woocommerce-jetpack' ) . '</a>' . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* replace_eu_vat_number_in_address_formats.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function replace_eu_vat_number_in_address_formats( $replacements, $args ) {
|
||||
$field_name = 'billing_' . $this->id;
|
||||
$replacements['{' . $field_name . '}'] = ( isset( $args[ $field_name ] ) ) ? $args[ $field_name ] : '';
|
||||
return $replacements;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_eu_vat_number_to_address_formats.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_eu_vat_number_to_address_formats( $address_formats ) {
|
||||
$field_name = 'billing_' . $this->id;
|
||||
$modified_address_formats = array();
|
||||
foreach ( $address_formats as $country => $address_format ) {
|
||||
$modified_address_formats[ $country ] = $address_format . "\n{" . $field_name . '}';
|
||||
}
|
||||
return $modified_address_formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_eu_vat_number_to_my_account_billing_address.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_eu_vat_number_to_my_account_billing_address( $fields, $customer_id, $name ) {
|
||||
if ( 'billing' === $name ) {
|
||||
$field_name = 'billing_' . $this->id;
|
||||
$fields[ $field_name ] = get_user_meta( $customer_id, $field_name, true );
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_eu_vat_number_to_order_billing_address.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_eu_vat_number_to_order_billing_address( $fields, $_order ) {
|
||||
$field_name = 'billing_' . $this->id;
|
||||
$fields[ $field_name ] = get_post_meta( wcj_get_order_id( $_order ), '_' . $field_name, true );
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_eu_vat_number_to_order_display.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.4.7
|
||||
*/
|
||||
function add_eu_vat_number_to_order_display( $order ) {
|
||||
$order_id = wcj_get_order_id( $order );
|
||||
$html = '';
|
||||
$option_name = '_billing_' . $this->id;
|
||||
$the_eu_vat_number = get_post_meta( $order_id, $option_name, true );
|
||||
if ( '' != $the_eu_vat_number ) {
|
||||
$the_label = get_option( 'wcj_eu_vat_number_field_label', __( 'EU VAT Number', 'woocommerce-jetpack' ) );
|
||||
$html .= '<p>' . '<strong>' . $the_label . '</strong>: ' . $the_eu_vat_number . '</p>';
|
||||
}
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* create_eu_countries_vat_rates_tool.
|
||||
*
|
||||
* @version 2.3.10
|
||||
* @since 2.3.10
|
||||
*/
|
||||
function create_eu_countries_vat_rates_tool() {
|
||||
return $this->eu_countries_vat_rates_tool->create_eu_countries_vat_rates_tool( $this->get_tool_header_html( 'eu_countries_vat_rates' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_default_checkout_billing_eu_vat_number.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function add_default_checkout_billing_eu_vat_number( $default_value, $field_key ) {
|
||||
if ( null !== ( $eu_vat_number_to_check = wcj_session_get( 'wcj_eu_vat_number_to_check' ) ) ) {
|
||||
return $eu_vat_number_to_check;
|
||||
} elseif ( is_user_logged_in() ) {
|
||||
$current_user = wp_get_current_user();
|
||||
if ( $meta = get_user_meta( $current_user->ID, 'billing_eu_vat_number', true ) ) {
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
return $default_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_eu_vat_number_customer_meta_field.
|
||||
*/
|
||||
function add_eu_vat_number_customer_meta_field( $fields ) {
|
||||
$fields['billing']['fields']['billing_eu_vat_number'] = array(
|
||||
'label' => get_option( 'wcj_eu_vat_number_field_label' ),
|
||||
'description' => ''
|
||||
);
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* start_session.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function start_session() {
|
||||
wcj_session_maybe_start();
|
||||
$args = array();
|
||||
if ( isset( $_POST['post_data'] ) ) {
|
||||
parse_str( $_POST['post_data'], $args );
|
||||
if ( isset( $args['billing_eu_vat_number'] ) && wcj_session_get( 'wcj_eu_vat_number_to_check' ) != $args['billing_eu_vat_number'] ) {
|
||||
wcj_session_set( 'wcj_is_eu_vat_number_valid', null );
|
||||
wcj_session_set( 'wcj_eu_vat_number_to_check', null );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_scripts.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function enqueue_scripts() {
|
||||
if ( 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) ) {
|
||||
wp_enqueue_script( 'wcj-eu-vat-number', wcj_plugin_url() . '/includes/js/wcj-eu-vat-number.js', array(), WCJ()->version, true );
|
||||
wp_localize_script( 'wcj-eu-vat-number', 'ajax_object', array(
|
||||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||
'add_progress_text' => get_option( 'wcj_eu_vat_number_add_progress_text', 'no' ),
|
||||
'progress_text_validating' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_validating', __( 'Validating VAT. Please wait...', 'woocommerce-jetpack' ) ) ),
|
||||
'progress_text_valid' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_valid', __( 'VAT is valid.', 'woocommerce-jetpack' ) ) ),
|
||||
'progress_text_not_valid' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_not_valid', __( 'VAT is not valid.', 'woocommerce-jetpack' ) ) ),
|
||||
'progress_text_validation_failed' => do_shortcode( get_option( 'wcj_eu_vat_number_progress_text_validation_failed', __( 'Validation failed. Please try again.', 'woocommerce-jetpack' ) ) ),
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wcj_validate_eu_vat_number.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function wcj_validate_eu_vat_number( $param ) {
|
||||
// if ( ! isset( $_GET['wcj_validate_eu_vat_number'] ) ) return;
|
||||
if ( isset( $_POST['wcj_eu_vat_number_to_check'] ) && '' != $_POST['wcj_eu_vat_number_to_check'] ) {
|
||||
$eu_vat_number_to_check = substr( $_POST['wcj_eu_vat_number_to_check'], 2 );
|
||||
$eu_vat_number_country_to_check = substr( $_POST['wcj_eu_vat_number_to_check'], 0, 2 );
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_eu_vat_number_check_ip_location_country', 'no' ) ) ) {
|
||||
$location = WC_Geolocation::geolocate_ip();
|
||||
if ( empty( $location['country'] ) ) {
|
||||
$location = wc_format_country_state_string( apply_filters( 'woocommerce_customer_default_location', get_option( 'woocommerce_default_country' ) ) );
|
||||
}
|
||||
$is_valid = ( $location['country'] === $eu_vat_number_country_to_check ) ?
|
||||
wcj_validate_vat( $eu_vat_number_country_to_check, $eu_vat_number_to_check ) :
|
||||
false;
|
||||
} else {
|
||||
$is_valid = wcj_validate_vat( $eu_vat_number_country_to_check, $eu_vat_number_to_check );
|
||||
}
|
||||
} else {
|
||||
$is_valid = null;
|
||||
}
|
||||
wcj_session_set( 'wcj_is_eu_vat_number_valid', $is_valid );
|
||||
wcj_session_set( 'wcj_eu_vat_number_to_check', $_POST['wcj_eu_vat_number_to_check'] );
|
||||
if ( false === $is_valid ) {
|
||||
echo '0';
|
||||
} elseif ( true === $is_valid ) {
|
||||
echo '1';
|
||||
} elseif ( null === $is_valid ) {
|
||||
echo '2';
|
||||
} else {
|
||||
echo '3'; // unexpected
|
||||
}
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_exclude_vat.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
// function maybe_exclude_vat( $matched_tax_rates, $args ) {
|
||||
function maybe_exclude_vat() {
|
||||
if (
|
||||
( is_checkout() || is_cart() || defined( 'WOOCOMMERCE_CHECKOUT' ) || defined( 'WOOCOMMERCE_CART' ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) &&
|
||||
! empty( WC()->customer ) &&
|
||||
'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) &&
|
||||
'yes' === get_option( 'wcj_eu_vat_number_disable_for_valid', 'yes' ) &&
|
||||
true === wcj_session_get( 'wcj_is_eu_vat_number_valid' ) && null !== wcj_session_get( 'wcj_eu_vat_number_to_check' )
|
||||
) {
|
||||
$preserve_base_country_check_passed = true;
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_eu_vat_number_preserve_in_base_country', 'no' ) ) ) {
|
||||
$location = wc_get_base_location();
|
||||
if ( empty( $location['country'] ) ) {
|
||||
$location = wc_format_country_state_string( apply_filters( 'woocommerce_customer_default_location', get_option( 'woocommerce_default_country' ) ) );
|
||||
}
|
||||
$selected_country = substr( wcj_session_get( 'wcj_eu_vat_number_to_check' ), 0, 2 );
|
||||
if ( 'EL' === $selected_country ) {
|
||||
$selected_country = 'GR';
|
||||
}
|
||||
$preserve_base_country_check_passed = ( strtoupper( $location['country'] ) !== strtoupper( $selected_country ) );
|
||||
}
|
||||
if ( $preserve_base_country_check_passed ) {
|
||||
/* $modified_matched_tax_rates = array();
|
||||
foreach ( $matched_tax_rates as $i => $matched_tax_rate ) {
|
||||
$matched_tax_rate['rate'] = 0;
|
||||
$modified_matched_tax_rates[ $i ] = $matched_tax_rate;
|
||||
}
|
||||
return $modified_matched_tax_rates; */
|
||||
WC()->customer->set_is_vat_exempt( true );
|
||||
} else {
|
||||
WC()->customer->set_is_vat_exempt( false );
|
||||
}
|
||||
} else {
|
||||
if ( ! empty( WC()->customer ) ) {
|
||||
WC()->customer->set_is_vat_exempt( false );
|
||||
}
|
||||
}
|
||||
// return $matched_tax_rates;
|
||||
}
|
||||
|
||||
/**
|
||||
* checkout_validate_vat.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function checkout_validate_vat( $_posted ) {
|
||||
if ( 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) ) {
|
||||
if (
|
||||
( 'yes' === get_option( 'wcj_eu_vat_number_field_required', 'no' ) && '' == $_posted['billing_eu_vat_number'] ) ||
|
||||
(
|
||||
( '' != $_posted['billing_eu_vat_number'] ) &&
|
||||
(
|
||||
null === wcj_session_get( 'wcj_is_eu_vat_number_valid' ) || false == wcj_session_get( 'wcj_is_eu_vat_number_valid' ) ||
|
||||
null === wcj_session_get( 'wcj_eu_vat_number_to_check' ) || $_posted['billing_eu_vat_number'] != wcj_session_get( 'wcj_eu_vat_number_to_check' )
|
||||
)
|
||||
)
|
||||
) {
|
||||
wc_add_notice(
|
||||
get_option( 'wcj_eu_vat_number_not_valid_message', __( '<strong>EU VAT Number</strong> is not valid.', 'woocommerce-jetpack' ) ),
|
||||
'error'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_billing_eu_vat_number_field_to_admin_order_display.
|
||||
*/
|
||||
function add_billing_eu_vat_number_field_to_admin_order_display( $fields ) {
|
||||
$fields[ $this->id ] = array(
|
||||
'type' => 'text',
|
||||
'label' => get_option( 'wcj_eu_vat_number_field_label' ),
|
||||
'show' => true,
|
||||
);
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_eu_vat_verify_button.
|
||||
*
|
||||
function add_eu_vat_verify_button( $field, $key, $args, $value ) {
|
||||
return ( 'billing_eu_vat_number' === $key ) ?
|
||||
$field . '<span style="font-size:smaller !important;">' . '[<a name="billing_eu_vat_number_verify" href="">' . __( 'Verify', 'woocommerce-jetpack' ) . '</a>]' . '</span>' :
|
||||
$field;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_eu_vat_number_checkout_field_to_frontend.
|
||||
*
|
||||
* @version 2.4.0
|
||||
*/
|
||||
function add_eu_vat_number_checkout_field_to_frontend( $fields ) {
|
||||
$fields['billing'][ 'billing_' . $this->id ] = array(
|
||||
'type' => 'text',
|
||||
// 'default' => ( null !== ( $eu_vat_number_to_check = wcj_session_get( 'wcj_eu_vat_number_to_check' ) ) ? $eu_vat_number_to_check : '' ),
|
||||
'label' => get_option( 'wcj_eu_vat_number_field_label' ),
|
||||
'description' => get_option( 'wcj_eu_vat_number_field_description' ),
|
||||
'placeholder' => get_option( 'wcj_eu_vat_number_field_placeholder' ),
|
||||
'required' => ( 'yes' === get_option( 'wcj_eu_vat_number_field_required', 'no' ) ) ? true : false,
|
||||
'custom_attributes' => array(),
|
||||
'clear' => ( 'yes' === get_option( 'wcj_eu_vat_number_field_clear', 'yes' ) ) ? true : false,
|
||||
'class' => array( get_option( 'wcj_eu_vat_number_field_class', 'form-row-wide' ) ),
|
||||
'validate' => ( 'yes' === get_option( 'wcj_eu_vat_number_validate', 'yes' ) ) ? array( 'eu-vat-number' ) : array(),
|
||||
);
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_EU_VAT_Number();
|
||||
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Export
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 2.5.4
|
||||
* @author Algoritmika Ltd.
|
||||
* @todo import products, customers and (maybe) orders
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Export_Import' ) ) :
|
||||
|
||||
class WCJ_Export_Import extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.5.4
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'export';
|
||||
$this->short_desc = __( 'Export', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'WooCommerce export tools.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-export-tools';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'export_customers' => array(
|
||||
'title' => __( 'Export Customers', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Export Customers.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'export_customers_from_orders' => array(
|
||||
'title' => __( 'Export Customers from Orders', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Export Customers (extracted from orders).', 'woocommerce-jetpack' ) . ' ' . __( 'Customers are identified by billing email.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'export_orders' => array(
|
||||
'title' => __( 'Export Orders', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Export Orders.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'export_orders_items' => array(
|
||||
'title' => __( 'Export Orders Items', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Export Orders Items.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'export_products' => array(
|
||||
'title' => __( 'Export Products', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Export Products.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
|
||||
$this->fields_helper = require_once( 'export/class-wcj-fields-helper.php' );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'init', array( $this, 'export_csv' ) );
|
||||
add_action( 'init', array( $this, 'export_xml' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* export.
|
||||
*
|
||||
* @version 2.5.9
|
||||
* @since 2.4.8
|
||||
* @todo when filtering now using strpos, but other options would be stripos (case-insensitive) or strict equality
|
||||
* @todo (maybe) do filtering directly in WP_Query
|
||||
*/
|
||||
function export( $tool_id ) {
|
||||
$data = array();
|
||||
switch ( $tool_id ) {
|
||||
case 'customers':
|
||||
$exporter = require_once( 'export/class-wcj-exporter-customers.php' );
|
||||
$data = $exporter->export_customers( $this->fields_helper );
|
||||
break;
|
||||
case 'customers_from_orders':
|
||||
$exporter = require_once( 'export/class-wcj-exporter-customers.php' );
|
||||
$data = $exporter->export_customers_from_orders( $this->fields_helper );
|
||||
break;
|
||||
case 'orders':
|
||||
$exporter = require_once( 'export/class-wcj-exporter-orders.php' );
|
||||
$data = $exporter->export_orders( $this->fields_helper );
|
||||
break;
|
||||
case 'orders_items':
|
||||
$exporter = require_once( 'export/class-wcj-exporter-orders.php' );
|
||||
$data = $exporter->export_orders_items( $this->fields_helper );
|
||||
break;
|
||||
case 'products':
|
||||
$exporter = require_once( 'export/class-wcj-exporter-products.php' );
|
||||
$data = $exporter->export_products( $this->fields_helper );
|
||||
break;
|
||||
}
|
||||
if ( isset( $_POST['wcj_export_filter_all_columns'] ) && '' != $_POST['wcj_export_filter_all_columns'] ) {
|
||||
foreach ( $data as $row_id => $row ) {
|
||||
if ( 0 == $row_id ) {
|
||||
continue;
|
||||
}
|
||||
$is_filtered = false;
|
||||
foreach ( $row as $cell ) {
|
||||
if ( false !== strpos( $cell, $_POST['wcj_export_filter_all_columns'] ) ) {
|
||||
$is_filtered = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! $is_filtered ) {
|
||||
unset( $data[ $row_id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if ( 1 == count( $data ) ) {
|
||||
return '<em>' . __( 'No results found.', 'woocommerce-jetpack' ) . '</em>';
|
||||
} */
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* export_xml.
|
||||
*
|
||||
* @version 2.5.9
|
||||
* @since 2.5.9
|
||||
* @todo templates for xml_start, xml_end, xml_item.
|
||||
* @todo strip_tags (same to Export WooCommerce plugin)
|
||||
*/
|
||||
function export_xml() {
|
||||
if ( isset( $_POST['wcj_export_xml'] ) ) {
|
||||
$data = $this->export( $_POST['wcj_export_xml'] );
|
||||
if ( is_array( $data ) ) {
|
||||
$xml = '';
|
||||
$xml .= '<?xml version = "1.0" encoding = "utf-8" ?>' . PHP_EOL . '<root>' . PHP_EOL;
|
||||
foreach ( $data as $row_num => $row ) {
|
||||
if ( 0 == $row_num ) {
|
||||
foreach ( $row as $cell_id => $cell_value ) {
|
||||
$cell_ids[ $cell_id ] = sanitize_title_with_dashes( $cell_value );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$xml .= '<item>' . PHP_EOL;
|
||||
foreach ( $row as $cell_id => $cell_value ) {
|
||||
$xml .= "\t" . '<' . $cell_ids[ $cell_id ] . '>' . $cell_value . '</' . $cell_ids[ $cell_id ] . '>' . PHP_EOL;
|
||||
}
|
||||
$xml .= '</item>' . PHP_EOL;
|
||||
}
|
||||
$xml .= '</root>';
|
||||
header( "Content-Disposition: attachment; filename=" . $_POST['wcj_export_xml'] . ".xml" );
|
||||
header( "Content-Type: Content-Type: text/html; charset=utf-8" );
|
||||
header( "Content-Description: File Transfer" );
|
||||
header( "Content-Length: " . strlen( $xml ) );
|
||||
echo $xml;
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* export_csv.
|
||||
*
|
||||
* @version 2.5.9
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function export_csv() {
|
||||
if ( isset( $_POST['wcj_export'] ) ) {
|
||||
$data = $this->export( $_POST['wcj_export'] );
|
||||
if ( is_array( $data ) ) {
|
||||
$csv = '';
|
||||
foreach ( $data as $row ) {
|
||||
$csv .= implode( get_option( 'wcj_export_csv_separator', ',' ), $row ) . PHP_EOL;
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_export_csv_add_utf_8_bom', 'yes' ) ) {
|
||||
$csv = "\xEF\xBB\xBF" . $csv; // UTF-8 BOM
|
||||
}
|
||||
header( "Content-Disposition: attachment; filename=" . $_POST['wcj_export'] . ".csv" );
|
||||
header( "Content-Type: Content-Type: text/html; charset=utf-8" );
|
||||
header( "Content-Description: File Transfer" );
|
||||
header( "Content-Length: " . strlen( $csv ) );
|
||||
echo $csv;
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* export_filter_fields.
|
||||
*
|
||||
* @version 2.5.9
|
||||
* @since 2.5.5
|
||||
* @todo filter each field separately
|
||||
*/
|
||||
function export_filter_fields( $tool_id ) {
|
||||
$fields = array();
|
||||
switch ( $tool_id ) {
|
||||
case 'orders':
|
||||
$fields = array(
|
||||
'wcj_filter_by_order_billing_country' => __( 'Filter by Billing Country', 'woocommerce-jetpack' ),
|
||||
'wcj_filter_by_product_title' => __( 'Filter by Product Title', 'woocommerce-jetpack' ),
|
||||
);
|
||||
break;
|
||||
case 'orders_items':
|
||||
$fields = array(
|
||||
'wcj_filter_by_order_billing_country' => __( 'Filter by Billing Country', 'woocommerce-jetpack' ),
|
||||
);
|
||||
break;
|
||||
}
|
||||
if ( ! empty( $fields ) ) {
|
||||
$data = array();
|
||||
foreach( $fields as $field_id => $field_desc ) {
|
||||
$field_value = ( isset( $_POST[ $field_id ] ) ) ? $_POST[ $field_id ] : '';
|
||||
$data[] = array(
|
||||
'<label for="' . $field_id . '">' . $field_desc . '</label>',
|
||||
'<input name="' . $field_id . '" id="' . $field_id . '" type="text" value="' . $field_value . '">',
|
||||
);
|
||||
}
|
||||
$data[] = array(
|
||||
'<button class="button-primary" type="submit" name="wcj_export_filter" value="' . $tool_id . '">' . __( 'Filter', 'woocommerce-jetpack' ) . '</button>',
|
||||
'',
|
||||
);
|
||||
return wcj_get_table_html( $data, array( 'table_class' => 'widefat', 'table_style' => 'width:50%;min-width:300px;', 'table_heading_type' => 'vertical', ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* export_date_fields.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 3.0.0
|
||||
* @todo mark current (i.e. active) link (if exists)
|
||||
*/
|
||||
function export_date_fields( $tool_id ) {
|
||||
$current_start_date = ( isset( $_GET['start_date'] ) ? $_GET['start_date'] : '' );
|
||||
$current_end_date = ( isset( $_GET['end_date'] ) ? $_GET['end_date'] : '' );
|
||||
$predefined_ranges = array();
|
||||
$predefined_ranges[] = '<a href="' . add_query_arg( 'range', 'all_time', remove_query_arg( array( 'start_date', 'end_date' ) ) ) . '">' .
|
||||
__( 'All time', 'woocommerce-jetpack' ) . '</a>';
|
||||
foreach ( array_merge( wcj_get_reports_standard_ranges(), wcj_get_reports_custom_ranges() ) as $range_id => $range_data ) {
|
||||
$link = add_query_arg( array(
|
||||
'start_date' => $range_data['start_date'],
|
||||
'end_date' => $range_data['end_date'],
|
||||
'range' => $range_id,
|
||||
) );
|
||||
$predefined_ranges[] = '<a href="' . $link . '">' . $range_data['title'] . '</a>';
|
||||
}
|
||||
$predefined_ranges = implode( ' | ', $predefined_ranges );
|
||||
$date_input_fields = '<form method="get" action="">' .
|
||||
'<input type="hidden" name="page" value="wcj-tools">' .
|
||||
'<input type="hidden" name="tab" value="export_' . $tool_id . '">' .
|
||||
'<strong>' . __( 'Custom:', 'woocommerce-jetpack' ) . '</strong>' . ' ' .
|
||||
'<input name="start_date" id="start_date" type="text" display="date" value="' . $current_start_date . '">' .
|
||||
'<strong>' . ' - ' . '</strong>' .
|
||||
'<input name="end_date" id="end_date" type="text" display="date" value="' . $current_end_date . '">' .
|
||||
' ' .
|
||||
'<button class="button-primary" name="range" id="range" type="submit" value="custom">' . __( 'Go', 'woocommerce-jetpack' ) . '</button>' .
|
||||
'</form>';
|
||||
return $predefined_ranges . '<br>' . $date_input_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* create_export_tool.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function create_export_tool( $tool_id ) {
|
||||
echo $this->get_tool_header_html( 'export_' . $tool_id );
|
||||
echo '<p>' . $this->export_date_fields( $tool_id ) . '</p>';
|
||||
if ( ! isset( $_GET['range'] ) ) {
|
||||
return;
|
||||
}
|
||||
echo '<form method="post" action="">';
|
||||
echo '<p>' . $this->export_filter_fields( $tool_id ) . '</p>';
|
||||
echo '<p>';
|
||||
echo '<button class="button-primary" type="submit" name="wcj_export" value="' . $tool_id . '">' . __( 'Download CSV', 'woocommerce-jetpack' ) . '</button>';
|
||||
echo ' ';
|
||||
echo '<button class="button-primary" type="submit" name="wcj_export_xml" value="' . $tool_id . '">' . __( 'Download XML', 'woocommerce-jetpack' ) . '</button>';
|
||||
echo '<button style="float:right;margin-right:10px;" class="button-primary" type="submit" name="wcj_export_filter" value="' . $tool_id . '">' . __( 'Filter by All Fields', 'woocommerce-jetpack' ) . '</button>';
|
||||
echo '<input style="float:right;margin-right:10px;" type="text" name="wcj_export_filter_all_columns" value="' . ( isset( $_POST['wcj_export_filter_all_columns'] ) ? $_POST['wcj_export_filter_all_columns'] : '' ) . '">';
|
||||
echo '</p>';
|
||||
echo '</form>';
|
||||
$data = $this->export( $tool_id );
|
||||
echo ( is_array( $data ) ) ? wcj_get_table_html( $data, array( 'table_class' => 'widefat striped' ) ) : $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* create_export_customers_tool.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function create_export_customers_tool() {
|
||||
$this->create_export_tool( 'customers' );
|
||||
}
|
||||
|
||||
/**
|
||||
* create_export_orders_tool.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function create_export_orders_tool() {
|
||||
$this->create_export_tool( 'orders' );
|
||||
}
|
||||
|
||||
/**
|
||||
* create_export_orders_items_tool.
|
||||
*
|
||||
* @version 2.5.9
|
||||
* @since 2.5.9
|
||||
*/
|
||||
function create_export_orders_items_tool() {
|
||||
$this->create_export_tool( 'orders_items' );
|
||||
}
|
||||
|
||||
/**
|
||||
* create_export_products_tool.
|
||||
*
|
||||
* @version 2.5.3
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function create_export_products_tool() {
|
||||
$this->create_export_tool( 'products' );
|
||||
}
|
||||
|
||||
/**
|
||||
* create_export_customers_from_orders_tool.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.3.9
|
||||
*/
|
||||
function create_export_customers_from_orders_tool() {
|
||||
$this->create_export_tool( 'customers_from_orders' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Export_Import();
|
||||
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Free Price
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.5.9
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Free_Price' ) ) :
|
||||
|
||||
class WCJ_Free_Price extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.5.9
|
||||
* @todo single in grouped is treated as "related"
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'free_price';
|
||||
$this->short_desc = __( 'Free Price Labels', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set free price labels.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-free-price-labels';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( WCJ_IS_WC_VERSION_BELOW_3 ) {
|
||||
add_filter( 'woocommerce_free_price_html', array( $this, 'modify_free_price_simple_external_custom' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_grouped_free_price_html', array( $this, 'modify_free_price_grouped' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_variable_free_price_html', array( $this, 'modify_free_price_variable' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_variation_free_price_html', array( $this, 'modify_free_price_variation' ), PHP_INT_MAX, 2 );
|
||||
} else {
|
||||
add_filter( 'woocommerce_get_price_html', array( $this, 'maybe_modify_price' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* are_all_prices_free
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function are_all_prices_free( $_product, $type ) {
|
||||
if ( 'variable' === $type ) {
|
||||
$prices = $_product->get_variation_prices( true );
|
||||
$min_price = current( $prices['price'] );
|
||||
$max_price = end( $prices['price'] );
|
||||
if ( '' !== $min_price && '' !== $max_price ) {
|
||||
return ( 0 == $min_price && 0 == $max_price );
|
||||
}
|
||||
} elseif ( 'variable' === $type ) {
|
||||
$child_prices = array();
|
||||
foreach ( $_product->get_children() as $child_id ) {
|
||||
$child = wc_get_product( $child_id );
|
||||
if ( '' !== $child->get_price() ) {
|
||||
$child_prices[] = wcj_get_product_display_price( $child );
|
||||
}
|
||||
}
|
||||
if ( ! empty( $child_prices ) ) {
|
||||
$min_price = min( $child_prices );
|
||||
$max_price = max( $child_prices );
|
||||
} else {
|
||||
$min_price = '';
|
||||
$max_price = '';
|
||||
}
|
||||
if ( '' !== $min_price && '' !== $max_price ) {
|
||||
return ( 0 == $min_price && 0 == $max_price );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_modify_price
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function maybe_modify_price( $price, $_product ) {
|
||||
if ( '' !== $price ) {
|
||||
if ( 0 == $_product->get_price() ) {
|
||||
if ( $_product->is_type( 'grouped' ) ) {
|
||||
return ( $this->are_all_prices_free( $_product, 'grouped' ) ) ? $this->modify_free_price_grouped( $price, $_product ) : $price;
|
||||
} elseif ( $_product->is_type( 'variable' ) ) {
|
||||
return ( $this->are_all_prices_free( $_product, 'variable' ) ) ? $this->modify_free_price_variable( $price, $_product ) : $price;
|
||||
} elseif ( $_product->is_type( 'variation' ) ) {
|
||||
return $this->modify_free_price_variation( $price, $_product );
|
||||
} else {
|
||||
return $this->modify_free_price_simple_external_custom( $price, $_product );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_view_id
|
||||
*
|
||||
* @version 2.5.9
|
||||
* @since 2.5.9
|
||||
*/
|
||||
function get_view_id( $product_id ) {
|
||||
$view = 'single'; // default
|
||||
if ( is_single( $product_id ) ) {
|
||||
$view = 'single';
|
||||
} elseif ( is_single() ) {
|
||||
$view = 'related';
|
||||
} elseif ( is_front_page() ) {
|
||||
$view = 'home';
|
||||
} elseif ( is_page() ) {
|
||||
$view = 'page';
|
||||
} elseif ( is_archive() ) {
|
||||
$view = 'archive';
|
||||
}
|
||||
return $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* modify_free_price_simple_external_custom.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.9
|
||||
*/
|
||||
function modify_free_price_simple_external_custom( $price, $_product ) {
|
||||
$default = '<span class="amount">' . __( 'Free!', 'woocommerce' ) . '</span>';
|
||||
return ( $_product->is_type( 'external' ) ) ?
|
||||
do_shortcode( get_option( 'wcj_free_price_external_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), $default ) ) :
|
||||
do_shortcode( get_option( 'wcj_free_price_simple_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), $default ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* modify_free_price_grouped.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.9
|
||||
*/
|
||||
function modify_free_price_grouped( $price, $_product ) {
|
||||
return do_shortcode( get_option( 'wcj_free_price_grouped_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), __( 'Free!', 'woocommerce' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* modify_free_price_variable.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.9
|
||||
*/
|
||||
function modify_free_price_variable( $price, $_product ) {
|
||||
return do_shortcode( apply_filters( 'booster_option', __( 'Free!', 'woocommerce' ), get_option( 'wcj_free_price_variable_' . $this->get_view_id( wcj_get_product_id_or_variation_parent_id( $_product ) ), __( 'Free!', 'woocommerce' ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* modify_free_price_variation.
|
||||
*
|
||||
* @version 2.5.9
|
||||
* @since 2.5.9
|
||||
*/
|
||||
function modify_free_price_variation( $price, $_product ) {
|
||||
return do_shortcode( apply_filters( 'booster_option', __( 'Free!', 'woocommerce' ), get_option( 'wcj_free_price_variable_variation', __( 'Free!', 'woocommerce' ) ) ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Free_Price();
|
||||
@@ -0,0 +1,348 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - General
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_General' ) ) :
|
||||
|
||||
class WCJ_General extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @todo expand `$this->desc`
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'general';
|
||||
$this->short_desc = __( 'General', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Custom roles tool. Shortcodes in WordPress text widgets.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-booster-general-tools';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'products_atts' => array(
|
||||
'title' => __( 'Products Attributes', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'All Products and All Attributes.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'custom_roles' => array(
|
||||
'title' => __( 'Add/Manage Custom Roles', 'woocommerce-jetpack' ),
|
||||
'tab_title' => __( 'Custom Roles', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Manage Custom Roles.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
// Recalculate cart totals
|
||||
if ( 'yes' === get_option( 'wcj_general_advanced_recalculate_cart_totals', 'no' ) ) {
|
||||
add_action( 'wp_loaded', array( $this, 'fix_mini_cart' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Product revisions
|
||||
if ( 'yes' === get_option( 'wcj_product_revisions_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_register_post_type_product', array( $this, 'enable_product_revisions' ) );
|
||||
}
|
||||
|
||||
// Shortcodes in text widgets
|
||||
if ( 'yes' === get_option( 'wcj_general_shortcodes_in_text_widgets_enabled' ) ) {
|
||||
add_filter( 'widget_text', 'do_shortcode' );
|
||||
}
|
||||
|
||||
// PayPal email per product
|
||||
if ( 'yes' === get_option( 'wcj_paypal_email_per_product_enabled', 'no' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_payment_gateways', array( $this, 'maybe_change_paypal_email' ) );
|
||||
}
|
||||
|
||||
// Session expiration
|
||||
if ( 'yes' === get_option( 'wcj_session_expiration_section_enabled', 'no' ) ) {
|
||||
add_filter( 'wc_session_expiring', array( $this, 'change_session_expiring' ), PHP_INT_MAX );
|
||||
add_filter( 'wc_session_expiration', array( $this, 'change_session_expiration' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Booster role user changer
|
||||
if ( wcj_is_booster_role_changer_enabled() ) {
|
||||
add_action( 'admin_bar_menu', array( $this, 'add_user_role_changer' ), PHP_INT_MAX );
|
||||
add_action( 'init', array( $this, 'change_user_role_meta' ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_user_role_meta.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) optionally via cookies
|
||||
*/
|
||||
function change_user_role_meta() {
|
||||
if ( isset( $_GET['wcj_booster_user_role'] ) ) {
|
||||
$current_user_id = get_current_user_id();
|
||||
update_user_meta( $current_user_id, '_' . 'wcj_booster_user_role', $_GET['wcj_booster_user_role'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_user_role_changer.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function add_user_role_changer( $wp_admin_bar ) {
|
||||
$current_user_id = get_current_user_id();
|
||||
$user_roles = wcj_get_user_roles_options();
|
||||
if ( '' != ( $current_booster_user_role = get_user_meta( $current_user_id, '_' . 'wcj_booster_user_role', true ) ) ) {
|
||||
$current_booster_user_role = ( isset( $user_roles[ $current_booster_user_role ] ) ) ? $user_roles[ $current_booster_user_role ] : $current_booster_user_role;
|
||||
$current_booster_user_role = ' [' . $current_booster_user_role . ']';
|
||||
}
|
||||
$args = array(
|
||||
'parent' => false,
|
||||
'id' => 'booster-user-role-changer',
|
||||
'title' => __( 'Booster User Role', 'woocommerce-jetpack' ) . $current_booster_user_role,
|
||||
'href' => false,
|
||||
);
|
||||
$wp_admin_bar->add_node( $args );
|
||||
foreach ( $user_roles as $user_role_key => $user_role_name ) {
|
||||
$args = array(
|
||||
'parent' => 'booster-user-role-changer',
|
||||
'id' => 'booster-user-role-changer-role-' . $user_role_key,
|
||||
'title' => $user_role_name,
|
||||
'href' => add_query_arg( 'wcj_booster_user_role', $user_role_key ),
|
||||
);
|
||||
$wp_admin_bar->add_node( $args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fix_mini_cart.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
* @todo this is only temporary solution!
|
||||
*/
|
||||
function fix_mini_cart() {
|
||||
if ( wcj_is_frontend() ) {
|
||||
if ( null !== ( $wc = WC() ) ) {
|
||||
if ( isset( $wc->cart ) ) {
|
||||
$wc->cart->calculate_totals();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_session_expiring.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function change_session_expiring( $the_time ) {
|
||||
return get_option( 'wcj_session_expiring', 47 * 60 * 60 );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_session_expiration.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function change_session_expiration( $the_time ) {
|
||||
return get_option( 'wcj_session_expiration', 48 * 60 * 60 );
|
||||
}
|
||||
|
||||
/**
|
||||
* create_custom_roles_tool.
|
||||
*
|
||||
* @version 2.5.3
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function create_custom_roles_tool() {
|
||||
if ( isset( $_POST['wcj_add_new_role'] ) ) {
|
||||
if (
|
||||
! isset( $_POST['wcj_custom_role_id'] ) || '' == $_POST['wcj_custom_role_id'] ||
|
||||
! isset( $_POST['wcj_custom_role_name'] ) || '' == $_POST['wcj_custom_role_name']
|
||||
) {
|
||||
echo '<p style="color:red;font-weight:bold;">' . __( 'Both fields are required!', 'woocommerce-jetpack') . '</p>';
|
||||
} else {
|
||||
if ( is_numeric( $_POST['wcj_custom_role_id'] ) ) {
|
||||
echo '<p style="color:red;font-weight:bold;">' . __( 'Role ID must not be numbers only!', 'woocommerce-jetpack') . '</p>';
|
||||
} else {
|
||||
$result = add_role( $_POST['wcj_custom_role_id'], $_POST['wcj_custom_role_name'] );
|
||||
if ( null !== $result ) {
|
||||
echo '<p style="color:green;font-weight:bold;">' . __( 'Role successfully added!', 'woocommerce-jetpack') . '</p>';
|
||||
} else {
|
||||
echo '<p style="color:red;font-weight:bold;">' . __( 'Role already exists!', 'woocommerce-jetpack') . '</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_GET['wcj_delete_role'] ) && '' != $_GET['wcj_delete_role'] ) {
|
||||
remove_role( $_GET['wcj_delete_role'] );
|
||||
echo '<p style="color:green;font-weight:bold;">' . sprintf( __( 'Role %s successfully deleted!', 'woocommerce-jetpack'), $_GET['wcj_delete_role'] ) . '</p>';
|
||||
}
|
||||
|
||||
echo $this->get_tool_header_html( 'custom_roles' );
|
||||
|
||||
$table_data = array();
|
||||
$table_data[] = array( __( 'ID', 'woocommerce-jetpack'), __( 'Name', 'woocommerce-jetpack'), __( 'Actions', 'woocommerce-jetpack'), );
|
||||
$existing_roles = wcj_get_user_roles();
|
||||
$default_wp_wc_roles = array( 'guest', 'administrator', 'editor', 'author', 'contributor', 'subscriber', 'customer', 'shop_manager', );
|
||||
foreach ( $existing_roles as $role_key => $role_data ) {
|
||||
$delete_html = ( in_array( $role_key, $default_wp_wc_roles ) )
|
||||
? ''
|
||||
: '<a href="' . add_query_arg( 'wcj_delete_role', $role_key ). '">' . __( 'Delete', 'woocommerce-jetpack') . '</a>';
|
||||
$table_data[] = array( $role_key, $role_data['name'], $delete_html );
|
||||
}
|
||||
echo '<h3>' . __( 'Existing Roles', 'woocommerce-jetpack') . '</h3>';
|
||||
echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) );
|
||||
|
||||
$table_data = array();
|
||||
$table_data[] = array( __( 'ID', 'woocommerce-jetpack'), '<input type="text" name="wcj_custom_role_id">' );
|
||||
$table_data[] = array( __( 'Name', 'woocommerce-jetpack'), '<input type="text" name="wcj_custom_role_name">' );
|
||||
echo '<h3>' . __( 'Add New Role', 'woocommerce-jetpack') . '</h3>';
|
||||
echo '<form method="post" action="' . remove_query_arg( 'wcj_delete_role' ) . '">' .
|
||||
wcj_get_table_html( $table_data, array( 'table_class' => 'widefat', 'table_heading_type' => 'vertical', 'table_style' => 'width:20%;min-width:300px;', ) )
|
||||
. '<p>' . '<input type="submit" name="wcj_add_new_role" class="button-primary" value="' . __( 'Add', 'woocommerce-jetpack' ) . '">' . '</p>'
|
||||
. '</form>';
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_change_paypal_email.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function maybe_change_paypal_email( $load_gateways ) {
|
||||
if ( isset( WC()->cart ) ) {
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
if ( '' != ( $email = get_post_meta( $values['product_id'], '_' . 'wcj_paypal_per_product_email', true ) ) ) {
|
||||
foreach ( $load_gateways as $key => $gateway ) {
|
||||
if ( is_string( $gateway ) && 'WC_Gateway_Paypal' === $gateway ) {
|
||||
$load_gateway = new $gateway();
|
||||
$load_gateway->receiver_email = $load_gateway->email = $load_gateway->settings['receiver_email'] = $load_gateway->settings['email'] = $email;
|
||||
$load_gateways[ $key ] = $load_gateway;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $load_gateways;
|
||||
}
|
||||
|
||||
/**
|
||||
* enable_product_revisions.
|
||||
*
|
||||
* @version 2.4.0
|
||||
* @since 2.4.0
|
||||
*/
|
||||
function enable_product_revisions( $args ) {
|
||||
$args['supports'][] = 'revisions';
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* create_products_atts_tool.
|
||||
*
|
||||
* @version 2.3.9
|
||||
* @since 2.3.9
|
||||
*/
|
||||
function create_products_atts_tool() {
|
||||
$html = '';
|
||||
$html .= $this->get_products_atts();
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_products_atts.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.3.9
|
||||
*/
|
||||
function get_products_atts() {
|
||||
|
||||
$total_products = 0;
|
||||
|
||||
$products_attributes = array();
|
||||
$attributes_names = array();
|
||||
$attributes_names['wcj_title'] = __( 'Product', 'woocommerce-jetpack' );
|
||||
$attributes_names['wcj_category'] = __( 'Category', 'woocommerce-jetpack' );
|
||||
|
||||
$offset = 0;
|
||||
$block_size = 96;
|
||||
while( true ) {
|
||||
|
||||
$args_products = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => $block_size,
|
||||
'orderby' => 'title',
|
||||
'order' => 'ASC',
|
||||
'offset' => $offset,
|
||||
);
|
||||
$loop_products = new WP_Query( $args_products );
|
||||
if ( ! $loop_products->have_posts() ) break;
|
||||
while ( $loop_products->have_posts() ) : $loop_products->the_post();
|
||||
|
||||
$total_products++;
|
||||
$product_id = $loop_products->post->ID;
|
||||
$the_product = wc_get_product( $product_id );
|
||||
|
||||
$products_attributes[ $product_id ]['wcj_title'] = '<a href="' . get_permalink( $product_id ) . '">' . $the_product->get_title() . '</a>';
|
||||
$products_attributes[ $product_id ]['wcj_category'] = ( WCJ_IS_WC_VERSION_BELOW_3 ? $the_product->get_categories() : wc_get_product_category_list( $product_id ) );
|
||||
|
||||
foreach ( $the_product->get_attributes() as $attribute ) {
|
||||
$products_attributes[ $product_id ][ $attribute['name'] ] = $the_product->get_attribute( $attribute['name'] );
|
||||
if ( ! isset( $attributes_names[ $attribute['name'] ] ) ) {
|
||||
$attributes_names[ $attribute['name'] ] = wc_attribute_label( $attribute['name'] );
|
||||
}
|
||||
}
|
||||
|
||||
endwhile;
|
||||
|
||||
$offset += $block_size;
|
||||
|
||||
}
|
||||
|
||||
$table_data = array();
|
||||
if ( isset( $_GET['wcj_attribute'] ) && '' != $_GET['wcj_attribute'] ) {
|
||||
$table_data[] = array(
|
||||
__( 'Product', 'woocommerce-jetpack' ),
|
||||
__( 'Category', 'woocommerce-jetpack' ),
|
||||
$_GET['wcj_attribute'],
|
||||
);
|
||||
} else {
|
||||
// $table_data[] = array_values( $attributes_names );
|
||||
$table_data[] = array_keys( $attributes_names );
|
||||
}
|
||||
foreach ( $attributes_names as $attributes_name => $attribute_title ) {
|
||||
|
||||
if ( isset( $_GET['wcj_attribute'] ) && '' != $_GET['wcj_attribute'] ) {
|
||||
if ( 'wcj_title' != $attributes_name && 'wcj_category' != $attributes_name && $_GET['wcj_attribute'] != $attributes_name ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $products_attributes as $product_id => $product_attributes ) {
|
||||
$table_data[ $product_id ][ $attributes_name ] = isset( $product_attributes[ $attributes_name ] ) ? $product_attributes[ $attributes_name ] : '';
|
||||
}
|
||||
}
|
||||
|
||||
return '<p>' . __( 'Total Products:', 'woocommerce-jetpack' ) . ' ' . $total_products . '</p>' . wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_General();
|
||||
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Global Discount
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.5.7
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Global_Discount' ) ) :
|
||||
|
||||
class WCJ_Global_Discount extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.5.7
|
||||
* @todo fee instead of discount
|
||||
* @todo regular price coefficient
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'global_discount';
|
||||
$this->short_desc = __( 'Global Discount', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add global discount to all products.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-shop-global-discount';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( wcj_is_frontend() ) {
|
||||
wcj_add_change_price_hooks( $this, PHP_INT_MAX, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
* @todo `WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER, 'woocommerce_variation_prices_regular_price', 'woocommerce_product_variation_get_regular_price'`
|
||||
*/
|
||||
function change_price( $price, $_product ) {
|
||||
$_current_filter = current_filter();
|
||||
if ( in_array( $_current_filter, array( WCJ_PRODUCT_GET_PRICE_FILTER, 'woocommerce_variation_prices_price', 'woocommerce_product_variation_get_price' ) ) ) {
|
||||
return $this->add_global_discount( $price, $_product, 'price' );
|
||||
} elseif ( in_array( $_current_filter, array( WCJ_PRODUCT_GET_SALE_PRICE_FILTER, 'woocommerce_variation_prices_sale_price', 'woocommerce_product_variation_get_sale_price' ) ) ) {
|
||||
return $this->add_global_discount( $price, $_product, 'sale_price' );
|
||||
} else {
|
||||
return $price;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_grouped.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function change_price_grouped( $price, $qty, $_product ) {
|
||||
if ( $_product->is_type( 'grouped' ) ) {
|
||||
foreach ( $_product->get_children() as $child_id ) {
|
||||
$the_price = get_post_meta( $child_id, '_price', true );
|
||||
$the_product = wc_get_product( $child_id );
|
||||
$the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
|
||||
if ( $the_price == $price ) {
|
||||
return $this->add_global_discount( $price, $the_product, 'price' );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate_price.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function calculate_price( $price, $coefficient, $group ) {
|
||||
$return_price = ( 'percent' === get_option( 'wcj_global_discount_sale_coefficient_type_' . $group, 'percent' ) ) ?
|
||||
( $price + $price * ( $coefficient / 100 ) ) :
|
||||
( $price + $coefficient );
|
||||
return ( $return_price >= 0 ) ? $return_price : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* check_if_applicable.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.5.7
|
||||
* @return bool
|
||||
*/
|
||||
function check_if_applicable( $_product, $group ) {
|
||||
return ( 'yes' === get_option( 'wcj_global_discount_sale_enabled_' . $group, 'yes' ) && $this->is_enabled_for_product( $_product, $group ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* is_enabled_for_product.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function is_enabled_for_product( $_product, $group ) {
|
||||
$product_id = wcj_get_product_id_or_variation_parent_id( $_product );
|
||||
return wcj_is_enabled_for_product( $product_id, array(
|
||||
'include_products' => get_option( 'wcj_global_discount_sale_products_incl_' . $group, '' ),
|
||||
'exclude_products' => get_option( 'wcj_global_discount_sale_products_excl_' . $group, '' ),
|
||||
'include_categories' => get_option( 'wcj_global_discount_sale_categories_incl_' . $group, '' ),
|
||||
'exclude_categories' => get_option( 'wcj_global_discount_sale_categories_excl_' . $group, '' ),
|
||||
'include_tags' => get_option( 'wcj_global_discount_sale_tags_incl_' . $group, '' ),
|
||||
'exclude_tags' => get_option( 'wcj_global_discount_sale_tags_excl_' . $group, '' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* check_if_applicable_by_product_scope.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function check_if_applicable_by_product_scope( $_product, $price, $price_type, $scope ) {
|
||||
$return = true;
|
||||
if ( 'sale_price' === $price_type ) {
|
||||
if ( 0 == $price ) {
|
||||
// The product is currently not on sale
|
||||
if ( 'only_on_sale' === $scope ) {
|
||||
$return = false;
|
||||
}
|
||||
} else {
|
||||
// The product is currently on sale
|
||||
if ( 'only_not_on_sale' === $scope ) {
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
} else { // if ( 'price' === $price_type )
|
||||
wcj_remove_change_price_hooks( $this, PHP_INT_MAX, false );
|
||||
if ( 'only_on_sale' === $scope && 0 == $_product->get_sale_price() ) {
|
||||
$return = false;
|
||||
} elseif ( 'only_not_on_sale' === $scope && 0 != $_product->get_sale_price() ) {
|
||||
$return = false;
|
||||
}
|
||||
wcj_add_change_price_hooks( $this, PHP_INT_MAX, false );
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_global_discount.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function add_global_discount( $price, $_product, $price_type ) {
|
||||
if ( 'price' === $price_type && '' === $price ) {
|
||||
return $price; // no changes
|
||||
}
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_global_discount_groups_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( ! $this->check_if_applicable( $_product, $i ) ) {
|
||||
continue; // no changes by current discount group
|
||||
}
|
||||
$coefficient = get_option( 'wcj_global_discount_sale_coefficient_' . $i, 0 );
|
||||
if ( 0 != $coefficient ) {
|
||||
if ( ! $this->check_if_applicable_by_product_scope( $_product, $price, $price_type, get_option( 'wcj_global_discount_sale_product_scope_' . $i, 'all' ) ) ) {
|
||||
continue; // no changes by current discount group
|
||||
}
|
||||
if ( 'sale_price' === $price_type && 0 == $price ) {
|
||||
$price = $_product->get_regular_price();
|
||||
}
|
||||
return $this->calculate_price( $price, $coefficient, $i ); // discount applied
|
||||
}
|
||||
}
|
||||
return $price; // no changes
|
||||
}
|
||||
|
||||
/**
|
||||
* get_variation_prices_hash.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function get_variation_prices_hash( $price_hash, $_product, $display ) {
|
||||
$wcj_global_discount_price_hash = array();
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_global_discount_groups_total_number', 1 ) );
|
||||
$wcj_global_discount_price_hash['total_number'] = $total_number;
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
$wcj_global_discount_price_hash[ 'enabled_' . $i ] = get_option( 'wcj_global_discount_sale_enabled_' . $i, 'yes' );
|
||||
$wcj_global_discount_price_hash[ 'type_' . $i ] = get_option( 'wcj_global_discount_sale_coefficient_type_' . $i, 'percent' );
|
||||
$wcj_global_discount_price_hash[ 'value_' . $i ] = get_option( 'wcj_global_discount_sale_coefficient_' . $i, 0 );
|
||||
$wcj_global_discount_price_hash[ 'scope_' . $i ] = get_option( 'wcj_global_discount_sale_product_scope_' . $i, 'all' );
|
||||
$wcj_global_discount_price_hash[ 'cats_in_' . $i ] = get_option( 'wcj_global_discount_sale_categories_incl_' . $i, '' );
|
||||
$wcj_global_discount_price_hash[ 'cats_ex_' . $i ] = get_option( 'wcj_global_discount_sale_categories_excl_' . $i, '' );
|
||||
$wcj_global_discount_price_hash[ 'tags_in_' . $i ] = get_option( 'wcj_global_discount_sale_tags_incl_' . $i, '' );
|
||||
$wcj_global_discount_price_hash[ 'tags_ex_' . $i ] = get_option( 'wcj_global_discount_sale_tags_excl_' . $i, '' );
|
||||
$wcj_global_discount_price_hash[ 'products_in_' . $i ] = get_option( 'wcj_global_discount_sale_products_incl_' . $i, '' );
|
||||
$wcj_global_discount_price_hash[ 'products_ex_' . $i ] = get_option( 'wcj_global_discount_sale_products_excl_' . $i, '' );
|
||||
}
|
||||
$price_hash['wcj_global_discount_price_hash'] = $wcj_global_discount_price_hash;
|
||||
return $price_hash;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Global_Discount();
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Left to Free Shipping
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.5.8
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Left_To_Free_Shipping' ) ) :
|
||||
|
||||
class WCJ_Left_To_Free_Shipping extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.5.8
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'left_to_free_shipping';
|
||||
$this->short_desc = __( 'Left to Free Shipping', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Display "left to free shipping" info.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-left-to-free-shipping';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( 'yes' === get_option( 'wcj_shipping_left_to_free_info_enabled_cart', 'no' ) ) {
|
||||
add_action(
|
||||
get_option( 'wcj_shipping_left_to_free_info_position_cart', 'woocommerce_after_cart_totals' ),
|
||||
array( $this, 'show_left_to_free_shipping_info_cart' ),
|
||||
get_option( 'wcj_shipping_left_to_free_info_priority_cart', 10 )
|
||||
);
|
||||
}
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_shipping_left_to_free_info_enabled_mini_cart', 'no' ) ) ) {
|
||||
add_action(
|
||||
get_option( 'wcj_shipping_left_to_free_info_position_mini_cart', 'woocommerce_after_mini_cart' ),
|
||||
array( $this, 'show_left_to_free_shipping_info_mini_cart' ),
|
||||
get_option( 'wcj_shipping_left_to_free_info_priority_mini_cart', 10 )
|
||||
);
|
||||
}
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_shipping_left_to_free_info_enabled_checkout', 'no' ) ) ) {
|
||||
add_action(
|
||||
get_option( 'wcj_shipping_left_to_free_info_position_checkout', 'woocommerce_checkout_after_order_review' ),
|
||||
array( $this, 'show_left_to_free_shipping_info_checkout' ),
|
||||
get_option( 'wcj_shipping_left_to_free_info_priority_checkout', 10 )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* show_left_to_free_shipping_info_checkout.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.4.4
|
||||
*/
|
||||
function show_left_to_free_shipping_info_checkout() {
|
||||
$this->show_left_to_free_shipping_info( do_shortcode( get_option( 'wcj_shipping_left_to_free_info_content_checkout', __( '%left_to_free% left to free shipping', 'woocommerce-jetpack' ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* show_left_to_free_shipping_info_mini_cart.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.4.4
|
||||
*/
|
||||
function show_left_to_free_shipping_info_mini_cart() {
|
||||
$this->show_left_to_free_shipping_info( do_shortcode( get_option( 'wcj_shipping_left_to_free_info_content_mini_cart', __( '%left_to_free% left to free shipping', 'woocommerce-jetpack' ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* show_left_to_free_shipping_info_cart.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.4.4
|
||||
*/
|
||||
function show_left_to_free_shipping_info_cart() {
|
||||
$this->show_left_to_free_shipping_info( do_shortcode( get_option( 'wcj_shipping_left_to_free_info_content_cart', __( '%left_to_free% left to free shipping', 'woocommerce-jetpack' ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* show_left_to_free_shipping_info.
|
||||
*
|
||||
* @version 2.4.4
|
||||
* @since 2.4.4
|
||||
*/
|
||||
function show_left_to_free_shipping_info( $content ) {
|
||||
echo wcj_get_left_to_free_shipping( $content );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Left_To_Free_Shipping();
|
||||
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Max Products per User
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Max_products_Per_User' ) ) :
|
||||
|
||||
class WCJ_Max_products_Per_User extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
* @todo (maybe) JS
|
||||
* @todo (maybe) zero quantity for "Guest"
|
||||
* @todo (maybe) editable sales data (i.e. change "Qty Bought" for product for user)
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'max_products_per_user';
|
||||
$this->short_desc = __( 'Maximum Products per User', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Limit number of items your (logged) customers can buy.', 'woocommerce-jetpack' );
|
||||
$this->extra_desc = __( 'Please note, that there is no maximum quantity set for not-logged (i.e. guest) users. Product quantities are updated, when order status is changed to completed.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-maximum-products-per-user';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( 'yes' === get_option( 'wcj_max_products_per_user_global_enabled', 'no' ) || 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_max_products_per_user_local_enabled', 'no' ) ) ) {
|
||||
add_action( 'woocommerce_checkout_process', array( $this, 'check_cart_quantities' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_before_cart', array( $this, 'check_cart_quantities' ), PHP_INT_MAX );
|
||||
if ( 'yes' === get_option( 'wcj_max_products_per_user_stop_from_seeing_checkout', 'no' ) ) {
|
||||
add_action( 'wp', array( $this, 'stop_from_seeing_checkout' ), PHP_INT_MAX );
|
||||
}
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_max_products_per_user_local_enabled', 'no' ) ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
add_action( 'woocommerce_order_status_completed', array( $this, 'save_quantities' ), PHP_INT_MAX );
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_report_meta_box' ) );
|
||||
add_action( 'admin_init', array( $this, 'calculate_data' ) );
|
||||
add_action( 'admin_notices', array( $this, 'calculate_data_notice' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate_data_notice.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function calculate_data_notice() {
|
||||
if ( isset( $_GET['wcj_max_products_per_user_calculate_data_finished'] ) ) {
|
||||
$class = 'notice notice-info';
|
||||
$message = __( 'Data re-calculated.', 'woocommerce-jetpack' ) . ' ' .
|
||||
sprintf( __( '%s order(s) processed.', 'woocommerce-jetpack' ), $_GET['wcj_max_products_per_user_calculate_data_finished'] );
|
||||
printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), esc_html( $message ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate_data.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
* @todo reset `wcj_max_products_per_user_report` and `wcj_max_products_per_user_saved` meta
|
||||
*/
|
||||
function calculate_data() {
|
||||
if ( isset( $_GET['wcj_max_products_per_user_calculate_data'] ) ) {
|
||||
$offset = 0;
|
||||
$block_size = 512;
|
||||
$total_orders = 0;
|
||||
while( true ) {
|
||||
$args = array(
|
||||
'post_type' => 'shop_order',
|
||||
'post_status' => 'wc-completed',
|
||||
'posts_per_page' => $block_size,
|
||||
'orderby' => 'ID',
|
||||
'order' => 'DESC',
|
||||
'offset' => $offset,
|
||||
'fields' => 'ids',
|
||||
);
|
||||
$loop = new WP_Query( $args );
|
||||
if ( ! $loop->have_posts() ) {
|
||||
break;
|
||||
}
|
||||
foreach ( $loop->posts as $_order_id ) {
|
||||
$this->save_quantities( $_order_id );
|
||||
$total_orders++;
|
||||
}
|
||||
$offset += $block_size;
|
||||
}
|
||||
wp_safe_redirect( add_query_arg( 'wcj_max_products_per_user_calculate_data_finished', $total_orders,
|
||||
remove_query_arg( 'wcj_max_products_per_user_calculate_data' ) ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_report_meta_box.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function add_report_meta_box() {
|
||||
add_meta_box(
|
||||
'wc-jetpack-' . $this->id . '-report',
|
||||
__( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Maximum Products per User: Sales Data', 'woocommerce-jetpack' ),
|
||||
array( $this, 'create_report_meta_box' ),
|
||||
'product',
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_report_meta_box.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function create_report_meta_box() {
|
||||
if ( $users_quantities = get_post_meta( get_the_ID(), '_' . 'wcj_max_products_per_user_report', true ) ) {
|
||||
$table_data = array();
|
||||
$table_data[] = array( __( 'User ID', 'woocommerce-jetpack' ), __( 'User Name', 'woocommerce-jetpack' ), __( 'Qty Bought', 'woocommerce-jetpack' ) );
|
||||
foreach ( $users_quantities as $user_id => $qty_bought ) {
|
||||
if ( 0 == $user_id ) {
|
||||
$user = __( 'Guest', 'woocommerce-jetpack' );
|
||||
} else {
|
||||
$user = get_user_by( 'id', $user_id );
|
||||
$user = ( isset( $user->data->user_nicename ) ? $user->data->user_nicename : '-' );
|
||||
}
|
||||
$table_data[] = array( $user_id, $user, $qty_bought );
|
||||
}
|
||||
echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'horizontal' ) );
|
||||
} else {
|
||||
echo '<em>' . __( 'No data yet.', 'woocommerce-jetpack' ) . '</em>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* save_quantities.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
* @todo (maybe) customizable `save_quantities` trigger
|
||||
*/
|
||||
function save_quantities( $order_id ) {
|
||||
if ( $order = wc_get_order( $order_id ) ) {
|
||||
if ( 'yes' !== get_post_meta( $order_id, '_' . 'wcj_max_products_per_user_saved', true ) ) {
|
||||
if ( sizeof( $order->get_items() ) > 0 ) {
|
||||
$user_id = ( WCJ_IS_WC_VERSION_BELOW_3 ? $order->customer_user : $order->get_customer_id() );
|
||||
foreach ( $order->get_items() as $item ) {
|
||||
if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) ) {
|
||||
$product_id = wcj_get_product_id_or_variation_parent_id( $product );
|
||||
$product_qty = $item->get_quantity();
|
||||
if ( '' == ( $users_quantities = get_post_meta( $product_id, '_' . 'wcj_max_products_per_user_report', true ) ) ) {
|
||||
$users_quantities = array();
|
||||
}
|
||||
if ( isset( $users_quantities[ $user_id ] ) ) {
|
||||
$product_qty += $users_quantities[ $user_id ];
|
||||
}
|
||||
$users_quantities[ $user_id ] = $product_qty;
|
||||
update_post_meta( $product_id, '_' . 'wcj_max_products_per_user_report', $users_quantities );
|
||||
}
|
||||
}
|
||||
}
|
||||
update_post_meta( $order_id, '_' . 'wcj_max_products_per_user_saved', 'yes' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_max_qty.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
* @todo (maybe) local - add "enabled/disabled" option
|
||||
* @todo (maybe) global - apply only to selected products (i.e. include/exclude products, cats, tags)
|
||||
* @todo (maybe) per user and/or per user role (both global and local)
|
||||
*/
|
||||
function get_max_qty( $product_id ) {
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_max_products_per_user_local_enabled', 'no' ) ) && 0 != ( $qty = get_post_meta( $product_id, '_' . 'wcj_max_products_per_user_qty', true ) ) ) {
|
||||
return $qty;
|
||||
} elseif ( 'yes' === get_option( 'wcj_max_products_per_user_global_enabled', 'no' ) ) {
|
||||
return get_option( 'wcj_max_products_per_user_global_max_qty', 1 );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* stop_from_seeing_checkout.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function stop_from_seeing_checkout() {
|
||||
if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) {
|
||||
return;
|
||||
}
|
||||
if ( ! $this->check_quantities( false ) ) {
|
||||
wp_safe_redirect( wc_get_cart_url() );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check_cart_quantities.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function check_cart_quantities() {
|
||||
$this->check_quantities();
|
||||
}
|
||||
|
||||
/**
|
||||
* check_quantities.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function check_quantities( $add_notices = true ) {
|
||||
$result = true;
|
||||
if ( ! isset( WC()->cart ) ) {
|
||||
return $result;
|
||||
}
|
||||
if ( 0 == ( $current_user_id = wcj_get_current_user_id() ) ) {
|
||||
return $result;
|
||||
}
|
||||
$cart_item_quantities = WC()->cart->get_cart_item_quantities();
|
||||
if ( empty( $cart_item_quantities ) || ! is_array( $cart_item_quantities ) ) {
|
||||
return $result;
|
||||
}
|
||||
$is_cart = ( function_exists( 'is_cart' ) && is_cart() );
|
||||
foreach ( $cart_item_quantities as $_product_id => $cart_item_quantity ) {
|
||||
if ( 0 == ( $max_qty = $this->get_max_qty( $_product_id ) ) ) {
|
||||
continue;
|
||||
}
|
||||
$user_already_bought = 0;
|
||||
if ( ( $users_quantities = get_post_meta( $_product_id, '_' . 'wcj_max_products_per_user_report', true ) ) && isset( $users_quantities[ $current_user_id ] ) ) {
|
||||
$user_already_bought = $users_quantities[ $current_user_id ];
|
||||
}
|
||||
if ( ( $user_already_bought + $cart_item_quantity ) > $max_qty ) {
|
||||
if ( $add_notices ) {
|
||||
$result = false;
|
||||
$product = wc_get_product( $_product_id );
|
||||
$replaced_values = array(
|
||||
'%max_qty%' => $max_qty,
|
||||
'%product_title%' => $product->get_title(),
|
||||
'%qty_already_bought%' => $user_already_bought,
|
||||
'%remaining_qty%' => max( ( $max_qty - $user_already_bought ), 0 ),
|
||||
);
|
||||
$message = get_option( 'wcj_max_products_per_user_message',
|
||||
__( 'You can only buy maximum %max_qty% pcs. of %product_title% (you already bought %qty_already_bought% pcs.).', 'woocommerce-jetpack' ) );
|
||||
$message = str_replace( array_keys( $replaced_values ), $replaced_values, $message );
|
||||
if ( $is_cart ) {
|
||||
wc_print_notice( $message, 'notice' );
|
||||
} else {
|
||||
wc_add_notice( $message, 'error' );
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Max_products_Per_User();
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Mini Cart Custom Info
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Mini_Cart' ) ) :
|
||||
|
||||
class WCJ_Mini_Cart extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'mini_cart';
|
||||
$this->short_desc = __( 'Mini Cart Custom Info', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add custom info to the mini cart widget.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-mini-cart';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_mini_cart_custom_info_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
add_action(
|
||||
get_option( 'wcj_mini_cart_custom_info_hook_' . $i, 'woocommerce_after_mini_cart' ),
|
||||
array( $this, 'add_mini_cart_custom_info' ),
|
||||
get_option( 'wcj_mini_cart_custom_info_priority_' . $i, 10 )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_mini_cart_custom_info.
|
||||
*
|
||||
* @version 2.4.6
|
||||
*/
|
||||
function add_mini_cart_custom_info() {
|
||||
$current_filter = current_filter();
|
||||
$current_filter_priority = wcj_current_filter_priority();
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_mini_cart_custom_info_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if (
|
||||
'' != get_option( 'wcj_mini_cart_custom_info_content_' . $i ) &&
|
||||
$current_filter === get_option( 'wcj_mini_cart_custom_info_hook_' . $i, 'woocommerce_after_mini_cart' ) &&
|
||||
$current_filter_priority == get_option( 'wcj_mini_cart_custom_info_priority_' . $i, 10 )
|
||||
) {
|
||||
echo do_shortcode( get_option( 'wcj_mini_cart_custom_info_content_' . $i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Mini_Cart();
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Modules By User Roles
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Modules_By_User_Roles' ) ) :
|
||||
|
||||
class WCJ_Modules_By_User_Roles extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'modules_by_user_roles';
|
||||
$this->short_desc = __( 'Modules By User Roles', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Enable/disable Booster for WooCommerce modules by user roles.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-booster-modules-by-user-roles';
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Modules_By_User_Roles();
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - More Button Labels
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_More_Button_Labels' ) ) :
|
||||
|
||||
class WCJ_More_Button_Labels extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.3.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'more_button_labels';
|
||||
$this->short_desc = __( 'More Button Labels', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set "Place order" button label.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-more-button-labels';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_order_button_text', array( $this, 'set_order_button_text' ), PHP_INT_MAX );
|
||||
if ( 'yes' === get_option( 'wcj_checkout_place_order_button_override', 'no' ) ) {
|
||||
add_action( 'init', array( $this, 'override_order_button_text' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* override_order_button_text.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function override_order_button_text() {
|
||||
if ( function_exists( 'WC' ) && method_exists( WC(), 'payment_gateways' ) && isset( WC()->payment_gateways()->payment_gateways ) ) {
|
||||
foreach ( WC()->payment_gateways()->payment_gateways as &$payment_gateway ) {
|
||||
$payment_gateway->order_button_text = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set_order_button_text.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function set_order_button_text( $current_text ) {
|
||||
return ( '' != ( $new_text = get_option( 'wcj_checkout_place_order_button_text', '' ) ) ) ? $new_text : $current_text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_More_Button_Labels();
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Multicurrency Product Base Price
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.4.8
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Multicurrency_Base_Price' ) ) :
|
||||
|
||||
class WCJ_Multicurrency_Base_Price extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'multicurrency_base_price';
|
||||
$this->short_desc = __( 'Multicurrency Product Base Price', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Enter prices for products in different currencies.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-multicurrency-product-base-price';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
|
||||
add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol_on_product_edit' ), PHP_INT_MAX, 2 );
|
||||
|
||||
$this->do_convert_in_back_end = ( 'yes' === get_option( 'wcj_multicurrency_base_price_do_convert_in_back_end', 'no' ) );
|
||||
|
||||
if ( $this->do_convert_in_back_end || wcj_is_frontend() ) {
|
||||
wcj_add_change_price_hooks( $this, PHP_INT_MAX - 10, false );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_grouped.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function change_price_grouped( $price, $qty, $_product ) {
|
||||
if ( $_product->is_type( 'grouped' ) ) {
|
||||
foreach ( $_product->get_children() as $child_id ) {
|
||||
$the_price = get_post_meta( $child_id, '_price', true );
|
||||
$the_product = wc_get_product( $child_id );
|
||||
$the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
|
||||
if ( $the_price == $price ) {
|
||||
return $this->change_price( $price, $the_product );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function change_price( $price, $_product ) {
|
||||
return wcj_price_by_product_base_currency( $price, wcj_get_product_id_or_variation_parent_id( $_product ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* get_variation_prices_hash.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function get_variation_prices_hash( $price_hash, $_product, $display ) {
|
||||
$multicurrency_base_price_currency = get_post_meta( wcj_get_product_id_or_variation_parent_id( $_product, true ), '_' . 'wcj_multicurrency_base_price_currency', true );
|
||||
$price_hash['wcj_multicurrency_base_price'] = array(
|
||||
'currency' => $multicurrency_base_price_currency,
|
||||
'exchange_rate' => wcj_get_currency_exchange_rate_product_base_currency( $multicurrency_base_price_currency ),
|
||||
'rounding' => get_option( 'wcj_multicurrency_base_price_round_enabled', 'no' ),
|
||||
'rounding_precision' => get_option( 'wcj_multicurrency_base_price_round_precision', get_option( 'woocommerce_price_num_decimals' ) ),
|
||||
'save_prices' => get_option( 'wcj_multicurrency_base_price_save_prices', 'no' ),
|
||||
);
|
||||
return $price_hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_currency_symbol_on_product_edit.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function change_currency_symbol_on_product_edit( $currency_symbol, $currency ) {
|
||||
if ( is_admin() ) {
|
||||
global $pagenow;
|
||||
if (
|
||||
( 'post.php' === $pagenow && isset( $_GET['action'] ) && 'edit' === $_GET['action'] ) || // admin product edit page
|
||||
( ! $this->do_convert_in_back_end && 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'] ) // admin products list
|
||||
) {
|
||||
$multicurrency_base_price_currency = get_post_meta( get_the_ID(), '_' . 'wcj_multicurrency_base_price_currency', true );
|
||||
if ( '' != $multicurrency_base_price_currency ) {
|
||||
return wcj_get_currency_symbol( $multicurrency_base_price_currency );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $currency_symbol;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Multicurrency_Base_Price();
|
||||
@@ -0,0 +1,337 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Multicurrency (Currency Switcher)
|
||||
*
|
||||
* @version 3.5.1
|
||||
* @since 2.4.3
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Multicurrency' ) ) :
|
||||
|
||||
class WCJ_Multicurrency extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.4.5
|
||||
* @todo check if we can just always execute `init()` on `init` hook
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'multicurrency';
|
||||
$this->short_desc = __( 'Multicurrency (Currency Switcher)', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add multiple currencies (currency switcher) to WooCommerce.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-multicurrency-currency-switcher';
|
||||
$this->extra_desc = sprintf( __( 'After setting currencies in the Currencies Options section below, use %s <strong>widget</strong>, or %s <strong>shortcode</strong>. If you want to insert switcher in your <strong>PHP code</strong>, just use %s code.', 'woocommerce-jetpack' ),
|
||||
'<em>' . __( 'Booster - Multicurrency Switcher', 'woocommerce-jetpack' ) . '</em>',
|
||||
'<code>[wcj_currency_select_drop_down_list]</code>',
|
||||
'<code>echo do_shortcode( \'[wcj_currency_select_drop_down_list]\' );</code>' );
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
$this->price_hooks_priority = wcj_get_module_price_hooks_priority( 'multicurrency' );
|
||||
|
||||
// Session
|
||||
if ( 'wc' === WCJ_SESSION_TYPE ) {
|
||||
// `init()` executed on `init` hook because we need to use `WC()->session`
|
||||
add_action( 'init', array( $this, 'init' ) );
|
||||
} else {
|
||||
$this->init();
|
||||
}
|
||||
|
||||
$this->add_hooks();
|
||||
|
||||
if ( 'yes' === get_option( 'wcj_multicurrency_per_product_enabled' , 'yes' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
if ( is_admin() ) {
|
||||
include_once( 'reports/class-wcj-currency-reports.php' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_hooks.
|
||||
*
|
||||
* @version 3.5.1
|
||||
*/
|
||||
function add_hooks() {
|
||||
if ( wcj_is_frontend() ) {
|
||||
|
||||
// Prices - Compatibility - "WooCommerce TM Extra Product Options" plugin
|
||||
add_filter( 'woocommerce_tm_epo_price_on_cart', array( $this, 'change_price_by_currency_tm_extra_product_options_plugin_cart' ), $this->price_hooks_priority, 1 );
|
||||
add_filter( 'wc_epo_price', array( $this, 'change_price_by_currency_tm_extra_product_options_plugin' ), $this->price_hooks_priority, 3 );
|
||||
|
||||
// Currency hooks
|
||||
add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), $this->price_hooks_priority, 2 );
|
||||
add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), $this->price_hooks_priority, 1 );
|
||||
|
||||
// Add "Change Price" hooks
|
||||
wcj_add_change_price_hooks( $this, $this->price_hooks_priority );
|
||||
|
||||
// "WooCommerce Product Add-ons" plugin
|
||||
add_filter( 'get_product_addons', array( $this, 'change_price_addons' ) );
|
||||
|
||||
// Additional Price Filters
|
||||
$this->additional_price_filters = get_option( 'wcj_multicurrency_switcher_additional_price_filters', '' );
|
||||
if ( ! empty( $this->additional_price_filters ) ) {
|
||||
$this->additional_price_filters = array_map( 'trim', explode( PHP_EOL, $this->additional_price_filters ) );
|
||||
foreach ( $this->additional_price_filters as $additional_price_filter ) {
|
||||
add_filter( $additional_price_filter, array( $this, 'change_price' ), $this->price_hooks_priority, 2 );
|
||||
}
|
||||
} else {
|
||||
$this->additional_price_filters = array();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* init.
|
||||
*
|
||||
* @version 3.4.5
|
||||
* @since 3.4.5
|
||||
*/
|
||||
function init() {
|
||||
wcj_session_maybe_start();
|
||||
if ( isset( $_REQUEST['wcj-currency'] ) ) {
|
||||
wcj_session_set( 'wcj-currency', $_REQUEST['wcj-currency'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_addons.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function change_price_addons( $addons ) {
|
||||
foreach ( $addons as $addon_key => $addon ) {
|
||||
if ( isset( $addon['options'] ) ) {
|
||||
foreach ( $addon['options'] as $option_key => $option ) {
|
||||
if ( isset( $option['price'] ) ) {
|
||||
$addons[ $addon_key ]['options'][ $option_key ]['price'] = $this->change_price( $option['price'], null );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $addons;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_by_currency_tm_extra_product_options_plugin_cart.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function change_price_by_currency_tm_extra_product_options_plugin_cart( $price ) {
|
||||
return $this->change_price( $price, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_by_currency_tm_extra_product_options_plugin.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function change_price_by_currency_tm_extra_product_options_plugin( $price, $type, $post_id ) {
|
||||
return $this->change_price( $price, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_grouped.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function change_price_grouped( $price, $qty, $_product ) {
|
||||
if ( $_product->is_type( 'grouped' ) ) {
|
||||
if ( 'yes' === get_option( 'wcj_multicurrency_per_product_enabled' , 'yes' ) ) {
|
||||
foreach ( $_product->get_children() as $child_id ) {
|
||||
$the_price = get_post_meta( $child_id, '_price', true );
|
||||
$the_product = wc_get_product( $child_id );
|
||||
$the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
|
||||
if ( $the_price == $price ) {
|
||||
return $this->change_price( $price, $the_product );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return $this->change_price( $price, null );
|
||||
}
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_variation_prices_hash.
|
||||
*
|
||||
* @version 3.5.0
|
||||
*/
|
||||
function get_variation_prices_hash( $price_hash, $_product, $display ) {
|
||||
$currency_code = $this->get_current_currency_code();
|
||||
$price_hash['wcj_multicurrency'] = array(
|
||||
'currency' => $currency_code,
|
||||
'exchange_rate' => $this->get_currency_exchange_rate( $currency_code ),
|
||||
'per_product' => get_option( 'wcj_multicurrency_per_product_enabled', 'yes' ),
|
||||
'rounding' => get_option( 'wcj_multicurrency_rounding', 'no_round' ),
|
||||
'rounding_precision' => get_option( 'wcj_multicurrency_rounding_precision', absint( get_option( 'woocommerce_price_num_decimals', 2 ) ) ),
|
||||
);
|
||||
return $price_hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_currency_exchange_rate.
|
||||
*
|
||||
* @version 2.4.3
|
||||
*/
|
||||
function get_currency_exchange_rate( $currency_code ) {
|
||||
$currency_exchange_rate = 1;
|
||||
$total_number = apply_filters( 'booster_option', 2, get_option( 'wcj_multicurrency_total_number', 2 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( $currency_code === get_option( 'wcj_multicurrency_currency_' . $i ) ) {
|
||||
$currency_exchange_rate = get_option( 'wcj_multicurrency_exchange_rate_' . $i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $currency_exchange_rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* do_revert.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function do_revert() {
|
||||
return ( 'yes' === get_option( 'wcj_multicurrency_revert', 'no' ) && is_checkout() );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price.
|
||||
*
|
||||
* @version 3.1.2
|
||||
*/
|
||||
function change_price( $price, $_product ) {
|
||||
|
||||
if ( '' === $price ) {
|
||||
return $price;
|
||||
}
|
||||
|
||||
if ( $this->do_revert() ) {
|
||||
return $price;
|
||||
}
|
||||
|
||||
// Per product
|
||||
if ( 'yes' === get_option( 'wcj_multicurrency_per_product_enabled' , 'yes' ) && null != $_product ) {
|
||||
$_product_id = wcj_get_product_id( $_product );
|
||||
if ( '' != ( $regular_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_multicurrency_per_product_regular_price_' . $this->get_current_currency_code(), true ) ) ) {
|
||||
$_current_filter = current_filter();
|
||||
if ( 'woocommerce_get_price_including_tax' == $_current_filter || 'woocommerce_get_price_excluding_tax' == $_current_filter ) {
|
||||
return wcj_get_product_display_price( $_product );
|
||||
|
||||
} elseif ( WCJ_PRODUCT_GET_PRICE_FILTER == $_current_filter || 'woocommerce_variation_prices_price' == $_current_filter || 'woocommerce_product_variation_get_price' == $_current_filter || in_array( $_current_filter, $this->additional_price_filters ) ) {
|
||||
$sale_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_multicurrency_per_product_sale_price_' . $this->get_current_currency_code(), true );
|
||||
return ( '' != $sale_price_per_product && $sale_price_per_product < $regular_price_per_product ) ? $sale_price_per_product : $regular_price_per_product;
|
||||
|
||||
} elseif ( WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER == $_current_filter || 'woocommerce_variation_prices_regular_price' == $_current_filter || 'woocommerce_product_variation_get_regular_price' == $_current_filter ) {
|
||||
return $regular_price_per_product;
|
||||
|
||||
} elseif ( WCJ_PRODUCT_GET_SALE_PRICE_FILTER == $_current_filter || 'woocommerce_variation_prices_sale_price' == $_current_filter || 'woocommerce_product_variation_get_sale_price' == $_current_filter ) {
|
||||
$sale_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_multicurrency_per_product_sale_price_' . $this->get_current_currency_code(), true );
|
||||
return ( '' != $sale_price_per_product ) ? $sale_price_per_product : $price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Global
|
||||
if ( 1 != ( $currency_exchange_rate = $this->get_currency_exchange_rate( $this->get_current_currency_code() ) ) ) {
|
||||
$price = $price * $currency_exchange_rate;
|
||||
switch ( get_option( 'wcj_multicurrency_rounding', 'no_round' ) ) {
|
||||
case 'round':
|
||||
$price = round( $price, get_option( 'wcj_multicurrency_rounding_precision', absint( get_option( 'woocommerce_price_num_decimals', 2 ) ) ) );
|
||||
break;
|
||||
case 'round_up':
|
||||
$price = ceil( $price );
|
||||
break;
|
||||
case 'round_down':
|
||||
$price = floor( $price );
|
||||
break;
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
// No changes
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_currency_symbol.
|
||||
*
|
||||
* @version 2.5.0
|
||||
*/
|
||||
function change_currency_symbol( $currency_symbol, $currency ) {
|
||||
if ( $this->do_revert() ) {
|
||||
return $currency_symbol;
|
||||
}
|
||||
return wcj_get_currency_symbol( $this->get_current_currency_code( $currency ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* get_current_currency_code.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function get_current_currency_code( $default_currency = '' ) {
|
||||
if ( null !== ( $session_value = wcj_session_get( 'wcj-currency' ) ) ) {
|
||||
return $session_value;
|
||||
} else {
|
||||
$module_roles = get_option( 'wcj_multicurrency_role_defaults_roles', '' );
|
||||
if ( ! empty( $module_roles ) ) {
|
||||
$current_user_role = wcj_get_current_user_first_role();
|
||||
if ( in_array( $current_user_role, $module_roles ) ) {
|
||||
$roles_default_currency = get_option( 'wcj_multicurrency_role_defaults_' . $current_user_role, '' );
|
||||
if ( '' != $roles_default_currency ) {
|
||||
return $roles_default_currency;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $default_currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_currency_code.
|
||||
*
|
||||
* @version 2.5.0
|
||||
*/
|
||||
function change_currency_code( $currency ) {
|
||||
if ( $this->do_revert() ) {
|
||||
return $currency;
|
||||
}
|
||||
return $this->get_current_currency_code( $currency );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_shipping.
|
||||
*
|
||||
* @version 3.2.0
|
||||
*/
|
||||
function change_price_shipping( $package_rates, $package ) {
|
||||
if ( $this->do_revert() ) {
|
||||
return $package_rates;
|
||||
}
|
||||
$currency_exchange_rate = $this->get_currency_exchange_rate( $this->get_current_currency_code() );
|
||||
return wcj_change_price_shipping_package_rates( $package_rates, $currency_exchange_rate );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Multicurrency();
|
||||
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - My Account
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.9.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_My_Account' ) ) :
|
||||
|
||||
class WCJ_My_Account extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'my_account';
|
||||
$this->short_desc = __( 'My Account', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'WooCommerce "My Account" page customization.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-my-account';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_my_account_my_orders_actions', array( $this, 'maybe_add_my_account_order_actions' ), 10, 2 );
|
||||
add_action( 'wp_footer', array( $this, 'maybe_add_js_conformation' ) );
|
||||
add_action( 'init', array( $this, 'process_woocommerce_mark_order_status' ) );
|
||||
// Custom info
|
||||
if ( 'yes' === get_option( 'wcj_my_account_custom_info_enabled', 'no' ) ) {
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_my_account_custom_info_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
add_action(
|
||||
get_option( 'wcj_my_account_custom_info_hook_' . $i, 'woocommerce_account_dashboard' ),
|
||||
array( $this, 'add_my_account_custom_info' ),
|
||||
get_option( 'wcj_my_account_custom_info_priority_' . $i, 10 )
|
||||
);
|
||||
}
|
||||
}
|
||||
// Registration extra fields
|
||||
if ( 'yes' === get_option( 'wcj_my_account_registration_extra_fields_user_role_enabled', 'no' ) ) {
|
||||
add_action( 'woocommerce_register_form', array( $this, 'add_registration_extra_fields' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_created_customer', array( $this, 'process_registration_extra_fields' ), PHP_INT_MAX, 3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_registration_extra_fields.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @todo (maybe) more fields to choose from (i.e. not only "user role" field)
|
||||
* @todo (maybe) customizable position (check for other hooks or at least customizable priority on `woocommerce_register_form`)
|
||||
* @todo (maybe) move to new module (e.g. "Registration Form")
|
||||
*/
|
||||
function add_registration_extra_fields() {
|
||||
$user_roles_options_html = '';
|
||||
$current_user_role_input = ! empty( $_POST['wcj_user_role'] ) ? $_POST['wcj_user_role'] :
|
||||
get_option( 'wcj_my_account_registration_extra_fields_user_role_default', 'customer' );
|
||||
$user_roles_options = get_option( 'wcj_my_account_registration_extra_fields_user_role_options', array( 'customer' ) );
|
||||
$all_user_roles = wcj_get_user_roles_options();
|
||||
foreach ( $user_roles_options as $user_role_id ) {
|
||||
$user_roles_options_html .= '<option value="' . $user_role_id . '" ' . selected( $user_role_id, $current_user_role_input, false ) . '>' .
|
||||
( isset( $all_user_roles[ $user_role_id ] ) ? $all_user_roles[ $user_role_id ] : $user_role_id ) . '</option>';
|
||||
}
|
||||
?><p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
|
||||
<label for="reg_wcj_user_role"><?php esc_html_e( 'User role', 'woocommerce-jetpack' ); ?></label>
|
||||
<select name="wcj_user_role" id="reg_wcj_user_role"><?php echo $user_roles_options_html; ?></select>
|
||||
</p><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* process_registration_extra_fields.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @todo (maybe) optional admin confirmation for some user roles (probably will need to create additional `...-pending` user roles)
|
||||
*/
|
||||
function process_registration_extra_fields( $customer_id, $new_customer_data, $password_generated ) {
|
||||
if ( isset( $_POST['wcj_user_role'] ) && '' != $_POST['wcj_user_role'] ) {
|
||||
$user_roles_options = get_option( 'wcj_my_account_registration_extra_fields_user_role_options', array( 'customer' ) );
|
||||
if ( ! empty( $user_roles_options ) && in_array( $_POST['wcj_user_role'], $user_roles_options ) ) {
|
||||
wp_update_user( array( 'ID' => $customer_id, 'role' => $_POST['wcj_user_role'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_my_account_custom_info.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
*/
|
||||
function add_my_account_custom_info() {
|
||||
$current_filter = current_filter();
|
||||
$current_filter_priority = wcj_current_filter_priority();
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_my_account_custom_info_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if (
|
||||
'' != get_option( 'wcj_my_account_custom_info_content_' . $i ) &&
|
||||
$current_filter === get_option( 'wcj_my_account_custom_info_hook_' . $i, 'woocommerce_account_dashboard' ) &&
|
||||
$current_filter_priority == get_option( 'wcj_my_account_custom_info_priority_' . $i, 10 )
|
||||
) {
|
||||
echo do_shortcode( get_option( 'wcj_my_account_custom_info_content_' . $i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* maybe_add_my_account_order_actions.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @see http://snippet.fm/snippets/add-order-complete-action-to-woocommerce-my-orders-customer-table/
|
||||
*/
|
||||
function maybe_add_my_account_order_actions( $actions, $order ) {
|
||||
$statuses_to_add = get_option( 'wcj_my_account_add_order_status_actions', '' );
|
||||
if ( ! empty( $statuses_to_add ) ) {
|
||||
$all_statuses = wcj_get_order_statuses();
|
||||
foreach ( $statuses_to_add as $status_to_add ) {
|
||||
if ( $status_to_add != $order->get_status() ) {
|
||||
$actions[ 'wcj_mark_' . $status_to_add . '_by_customer' ] = array(
|
||||
'url' => wp_nonce_url( add_query_arg( array(
|
||||
'wcj_action' => 'wcj_woocommerce_mark_order_status',
|
||||
'status' => $status_to_add,
|
||||
'order_id' => $order->get_id() ) ), 'wcj-woocommerce-mark-order-status' ),
|
||||
'name' => $all_statuses[ $status_to_add ],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/*
|
||||
* maybe_add_js_conformation.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function maybe_add_js_conformation() {
|
||||
$statuses_to_add = get_option( 'wcj_my_account_add_order_status_actions', '' );
|
||||
if ( ! empty( $statuses_to_add ) ) {
|
||||
echo '<script>';
|
||||
foreach ( $statuses_to_add as $status_to_add ) {
|
||||
echo 'jQuery("a.wcj_mark_' . $status_to_add . '_by_customer").each( function() { jQuery(this).attr("onclick", "return confirm(\'' .
|
||||
__( 'Are you sure?', 'woocommerce-jetpack' ) . '\')") } );';
|
||||
}
|
||||
echo '</script>';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* process_woocommerce_mark_order_status.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function process_woocommerce_mark_order_status() {
|
||||
if (
|
||||
isset( $_GET['wcj_action'] ) && 'wcj_woocommerce_mark_order_status' === $_GET['wcj_action'] &&
|
||||
isset( $_GET['status'] ) &&
|
||||
isset( $_GET['order_id'] ) &&
|
||||
isset( $_GET['_wpnonce'] )
|
||||
) {
|
||||
if ( wp_verify_nonce( $_GET['_wpnonce'], 'wcj-woocommerce-mark-order-status' ) ) {
|
||||
$_order = wc_get_order( $_GET['order_id'] );
|
||||
if ( $_order->get_customer_id() === get_current_user_id() ) {
|
||||
$_order->update_status( $_GET['status'] );
|
||||
wp_safe_redirect( remove_query_arg( array( 'wcj_action', 'status', 'order_id', '_wpnonce' ) ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_My_Account();
|
||||
@@ -0,0 +1,480 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Offer Price
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.9.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Offer_Price' ) ) :
|
||||
|
||||
class WCJ_Offer_Price extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.9.0
|
||||
* @todo settings - more info about position priorities, e.g.: __( 'Standard priorities for "Inside single product summary": title - 5, rating - 10, price - 10, excerpt - 20, add to cart - 30, meta - 40, sharing - 50', 'woocommerce-jetpack' )
|
||||
* @todo (maybe) css - customizable fonts etc.
|
||||
* @todo (maybe) css - better default colors
|
||||
* @todo (maybe) better solution for the form hook (instead of `woocommerce_before_main_content`)
|
||||
* @todo (maybe) per product settings - add "use global values/use values below" for price step etc. (instead of placeholders etc.)
|
||||
* @todo (maybe) recheck multicurrency
|
||||
* @todo (maybe) more "Make an offer" button position options (on both single and archives)
|
||||
* @todo (maybe) variations and grouped products
|
||||
* @todo (maybe) add shortcode
|
||||
* @todo (maybe) offers history - option for disabling
|
||||
* @todo (maybe) offers history - global (i.e. for all products)
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'offer_price';
|
||||
$this->short_desc = __( 'Offer Your Price', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Let your customers to suggest their price for products.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-offer-your-product-price';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( 'disable' != ( $_hook = get_option( 'wcj_offer_price_button_position', 'woocommerce_single_product_summary' ) ) ) {
|
||||
add_action(
|
||||
$_hook,
|
||||
array( $this, 'add_offer_price_button' ),
|
||||
get_option( 'wcj_offer_price_button_position_priority', 31 )
|
||||
);
|
||||
}
|
||||
if ( 'disable' != ( $_hook = apply_filters( 'booster_option', 'disable', get_option( 'wcj_offer_price_button_position_archives', 'disable' ) ) ) ) {
|
||||
add_action(
|
||||
$_hook,
|
||||
array( $this, 'add_offer_price_button' ),
|
||||
get_option( 'wcj_offer_price_button_position_priority_archives', 10 )
|
||||
);
|
||||
}
|
||||
add_action( 'woocommerce_before_main_content', array( $this, 'add_offer_price_form' ) );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'init', array( $this, 'offer_price' ) );
|
||||
if ( 'per_product' === apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
// Offer history
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_offer_price_history_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'delete_offer_price_product_history' ), PHP_INT_MAX, 2 );
|
||||
// CSS
|
||||
add_action( 'wp_head', array( $this, 'add_styling' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_styling.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.7.0
|
||||
*/
|
||||
function add_styling() {
|
||||
$styling_default = array(
|
||||
'form_content_width' => '80%',
|
||||
'form_header_back_color' => '#5cb85c',
|
||||
'form_header_text_color' => '#ffffff',
|
||||
'form_footer_back_color' => '#5cb85c',
|
||||
'form_footer_text_color' => '#ffffff',
|
||||
);
|
||||
$styling_options = get_option( 'wcj_offer_price_styling', array() );
|
||||
foreach ( $styling_default as $option => $default ) {
|
||||
if ( ! isset( $styling_options[ $option ] ) ) {
|
||||
$styling_options[ $option ] = $default;
|
||||
}
|
||||
}
|
||||
echo "<style type=\"text/css\">
|
||||
.wcj-offer-price-modal-content {
|
||||
width: {$styling_options['form_content_width']};
|
||||
}
|
||||
.wcj-offer-modal-header {
|
||||
background-color: {$styling_options['form_header_back_color']};
|
||||
color: {$styling_options['form_header_text_color']};
|
||||
}
|
||||
.wcj-offer-modal-header h1, .wcj-offer-modal-header h2, .wcj-offer-modal-header h3, .wcj-offer-modal-header h4, .wcj-offer-modal-header h5, .wcj-offer-modal-header h6 {
|
||||
color: {$styling_options['form_header_text_color']};
|
||||
}
|
||||
.wcj-offer-price-modal-footer {
|
||||
background-color: {$styling_options['form_footer_back_color']};
|
||||
color: {$styling_options['form_footer_text_color']};
|
||||
}
|
||||
.wcj-offer-price-modal-footer h1, .wcj-offer-price-modal-footer h2, .wcj-offer-price-modal-footer h3, .wcj-offer-price-modal-footer h4, .wcj-offer-price-modal-footer h5, .wcj-offer-price-modal-footer h6 {
|
||||
color: {$styling_options['form_footer_text_color']};
|
||||
}
|
||||
</style>";
|
||||
}
|
||||
|
||||
/**
|
||||
* delete_offer_price_product_history.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) add successful deletion notice
|
||||
*/
|
||||
function delete_offer_price_product_history( $post_id, $post ) {
|
||||
if ( isset( $_POST['wcj_offer_price_delete_history'] ) ) {
|
||||
delete_post_meta( $post_id, '_' . 'wcj_price_offers' );
|
||||
add_action( 'admin_notices', array( $this, 'notice_delete_offer_price_product_history' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_offer_price_history_meta_box.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function add_offer_price_history_meta_box() {
|
||||
add_meta_box(
|
||||
'wc-booster-offer-price-history',
|
||||
__( 'Booster: Offer Price History', 'woocommerce-jetpack' ),
|
||||
array( $this, 'create_offer_price_history_meta_box' ),
|
||||
'product',
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_offer_price_history_meta_box.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function create_offer_price_history_meta_box() {
|
||||
if ( '' == ( $price_offers = get_post_meta( get_the_ID(), '_' . 'wcj_price_offers', true ) ) ) {
|
||||
echo '<em>' . __( 'No price offers yet.', 'woocommerce-jetpack' ) . '</em>';
|
||||
} else {
|
||||
$average_offers = array();
|
||||
$table_data = array();
|
||||
$table_data[] = array(
|
||||
__( 'Date', 'woocommerce-jetpack' ),
|
||||
__( 'Price', 'woocommerce-jetpack' ),
|
||||
__( 'Message', 'woocommerce-jetpack' ),
|
||||
__( 'Name', 'woocommerce-jetpack' ),
|
||||
__( 'Email', 'woocommerce-jetpack' ),
|
||||
__( 'Customer ID', 'woocommerce-jetpack' ),
|
||||
__( 'Sent to', 'woocommerce-jetpack' ),
|
||||
);
|
||||
$date_ant_time_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );
|
||||
$price_offers = array_reverse( $price_offers );
|
||||
foreach ( $price_offers as $price_offer ) {
|
||||
$table_data[] = array(
|
||||
date_i18n( $date_ant_time_format, $price_offer['offer_timestamp'] ),
|
||||
wc_price( $price_offer['offered_price'], array( 'currency' => $price_offer['currency_code'] ) ),
|
||||
$price_offer['customer_message'],
|
||||
$price_offer['customer_name'],
|
||||
$price_offer['customer_email'],
|
||||
$price_offer['customer_id'],
|
||||
$price_offer['sent_to'] . ( 'yes' === $price_offer['copy_to_customer'] ? '<br>' . $price_offer['customer_email'] : '' ),
|
||||
);
|
||||
if ( ! isset( $average_offers[ $price_offer['currency_code'] ] ) ) {
|
||||
$average_offers[ $price_offer['currency_code'] ] = array( 'total_offers' => 0, 'offers_sum' => 0 );
|
||||
}
|
||||
$average_offers[ $price_offer['currency_code'] ]['total_offers']++;
|
||||
$average_offers[ $price_offer['currency_code'] ]['offers_sum'] += $price_offer['offered_price'];
|
||||
}
|
||||
echo wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) );
|
||||
foreach ( $average_offers as $average_offer_currency_code => $average_offer_data ) {
|
||||
echo '<p>' . sprintf( __( 'Average offer: %s (from %s offer(s))', 'woocommerce-jetpack' ),
|
||||
wc_price( ( $average_offer_data['offers_sum'] / $average_offer_data['total_offers'] ), array( 'currency' => $average_offer_currency_code ) ),
|
||||
$average_offer_data['total_offers']
|
||||
) . '</p>';
|
||||
}
|
||||
echo '<p>' .
|
||||
'<input type="checkbox" id="wcj_offer_price_delete_history" name="wcj_offer_price_delete_history">' .
|
||||
'<label for="wcj_offer_price_delete_history">' . __( 'Delete history', 'woocommerce-jetpack' ) . '</label>' .
|
||||
wc_help_tip( __( 'Update product after checking the box.', 'woocommerce-jetpack' ) ) .
|
||||
'</p>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_scripts.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @see https://www.w3schools.com/howto/howto_css_modals.asp
|
||||
* @todo (maybe) enqueue only if really needed
|
||||
*/
|
||||
function enqueue_scripts() {
|
||||
wp_enqueue_style( 'wcj-offer-price', wcj_plugin_url() . '/includes/css/wcj-offer-price.css', array(), WCJ()->version );
|
||||
wp_enqueue_script( 'wcj-offer-price-js', wcj_plugin_url() . '/includes/js/wcj-offer-price.js', array( 'jquery' ), WCJ()->version, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* is_offer_price_enabled_for_product.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function is_offer_price_enabled_for_product( $product_id ) {
|
||||
switch ( apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) ) {
|
||||
case 'all_products':
|
||||
return true;
|
||||
case 'empty_prices':
|
||||
$_product = wc_get_product( $product_id );
|
||||
return ( '' === $_product->get_price() );
|
||||
case 'per_product':
|
||||
return ( 'yes' === get_post_meta( $product_id, '_' . 'wcj_offer_price_enabled', true ) );
|
||||
case 'per_category':
|
||||
return wcj_is_product_term( $product_id, get_option( 'wcj_offer_price_enabled_cats', array() ), 'product_cat' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_wcj_data_array.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) rethink `str_replace( '\'', '"', ... )`
|
||||
*/
|
||||
function get_wcj_data_array( $product_id ) {
|
||||
$is_per_product_enabled = ( 'per_product' === apply_filters( 'booster_option', 'all_products', get_option( 'wcj_offer_price_enabled_type', 'all_products' ) ) );
|
||||
// Price input - price step
|
||||
$price_step = ( ! $is_per_product_enabled || '' === ( $price_step_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_price_step', true ) ) ?
|
||||
get_option( 'wcj_offer_price_price_step', get_option( 'woocommerce_price_num_decimals' ) ) :
|
||||
$price_step_per_product
|
||||
);
|
||||
$price_step = sprintf( "%f", ( 1 / pow( 10, absint( $price_step ) ) ) );
|
||||
// Price input - min price
|
||||
$min_price = ( ! $is_per_product_enabled || '' === ( $min_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_min_price', true ) ) ?
|
||||
get_option( 'wcj_offer_price_min_price', 0 ) :
|
||||
$min_price_per_product
|
||||
);
|
||||
// Price input - max price
|
||||
$max_price = ( ! $is_per_product_enabled || '' === ( $max_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_max_price', true ) ) ?
|
||||
get_option( 'wcj_offer_price_max_price', 0 ) :
|
||||
$max_price_per_product
|
||||
);
|
||||
// Price input - default price
|
||||
$default_price = ( ! $is_per_product_enabled || '' === ( $default_price_per_product = get_post_meta( $product_id, '_' . 'wcj_offer_price_default_price', true ) ) ?
|
||||
get_option( 'wcj_offer_price_default_price', 0 ) :
|
||||
$default_price_per_product
|
||||
);
|
||||
// Price input - label
|
||||
$price_label = str_replace(
|
||||
'%currency_symbol%',
|
||||
get_woocommerce_currency_symbol(),
|
||||
get_option( 'wcj_offer_price_price_label', sprintf( __( 'Your price (%s)', 'woocommerce-jetpack' ), '%currency_symbol%' ) )
|
||||
);
|
||||
// Offer form - header
|
||||
$form_header = str_replace(
|
||||
'%product_title%',
|
||||
get_the_title(),
|
||||
get_option( 'wcj_offer_price_form_header_template', '<h3>' . sprintf( __( 'Suggest your price for %s', 'woocommerce-jetpack' ), '%product_title%' ) . '</h3>' )
|
||||
);
|
||||
return array(
|
||||
'price_step' => $price_step,
|
||||
'min_price' => $min_price,
|
||||
'max_price' => $max_price,
|
||||
'default_price' => $default_price,
|
||||
'price_label' => str_replace( '\'', '"', $price_label ),
|
||||
'form_header' => str_replace( '\'', '"', $form_header ),
|
||||
'product_id' => $product_id,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* add_offer_price_form.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) fix when empty header
|
||||
* @todo (maybe) style options for input fields (class, style)
|
||||
* @todo (maybe) form template
|
||||
* @todo (maybe) do_shortcode in form header and footer
|
||||
* @todo (maybe) logged user - check `nickname` and `billing_email`
|
||||
* @todo (maybe) better required asterix default
|
||||
* @todo (maybe) optional, additional and custom form fields
|
||||
*/
|
||||
function add_offer_price_form() {
|
||||
// Prepare logged user data
|
||||
$customer_name = '';
|
||||
$customer_email = '';
|
||||
$customer_id = 0;
|
||||
if ( is_user_logged_in() ) {
|
||||
$current_user = wp_get_current_user();
|
||||
$customer_id = $current_user->ID;
|
||||
if ( '' != ( $meta = get_user_meta( $current_user->ID, 'nickname', true ) ) ) {
|
||||
$customer_name = $meta;
|
||||
}
|
||||
if ( '' != ( $meta = get_user_meta( $current_user->ID, 'billing_email', true ) ) ) {
|
||||
$customer_email = $meta;
|
||||
}
|
||||
}
|
||||
// Header
|
||||
$offer_form_header = '<div class="wcj-offer-modal-header">' .
|
||||
'<span class="wcj-offer-price-form-close">×</span>' . '<div id="wcj-offer-form-header"></div>' .
|
||||
'</div>';
|
||||
// Footer
|
||||
$offer_form_footer = ( '' != ( $footer_template = get_option( 'wcj_offer_price_form_footer_template', '' ) ) ?
|
||||
'<div class="wcj-offer-price-modal-footer">' . /* do_shortcode */( $footer_template ) . '</div>' : '' );
|
||||
// Required HTML
|
||||
$required_html = get_option( 'wcj_offer_price_form_required_html', ' <abbr class="required" title="required">*</abbr>' );
|
||||
// Content - price
|
||||
$offer_form_content_price = '<label for="wcj-offer-price-price">' .
|
||||
'<span id="wcj-offer-price-price-label"></span>' . $required_html . '</label>' . '<br>' .
|
||||
'<input type="number" required id="wcj-offer-price-price" name="wcj-offer-price-price">';
|
||||
// Content - email
|
||||
$offer_form_content_email = '<label for="wcj-offer-price-customer-email">' . get_option( 'wcj_offer_price_customer_email', __( 'Your email', 'woocommerce-jetpack' ) ) .
|
||||
$required_html . '</label>' . '<br>' .
|
||||
'<input type="email" required id="wcj-offer-price-customer-email" name="wcj-offer-price-customer-email" value="' . $customer_email . '">';
|
||||
// Content - name
|
||||
$offer_form_content_name = '<label for="wcj-offer-price-customer-name">' . get_option( 'wcj_offer_price_customer_name', __( 'Your name', 'woocommerce-jetpack' ) ) .
|
||||
'</label>' . '<br>' .
|
||||
'<input type="text" id="wcj-offer-price-customer-name" name="wcj-offer-price-customer-name" value="' . $customer_name . '">';
|
||||
// Content - message
|
||||
$offer_form_content_message = '<label for="wcj-offer-price-message">' . get_option( 'wcj_offer_price_customer_message', __( 'Your message', 'woocommerce-jetpack' ) ) . '</label>' . '<br>' .
|
||||
'<textarea id="wcj-offer-price-message" name="wcj-offer-price-message"></textarea>';
|
||||
// Content - button
|
||||
$offer_form_content_button = '<input type="submit" id="wcj-offer-price-submit" name="wcj-offer-price-submit" value="' .
|
||||
get_option( 'wcj_offer_price_form_button_label', __( 'Send', 'woocommerce-jetpack' ) ) . '">';
|
||||
// Content - copy
|
||||
$offer_form_content_copy = '<label for="wcj-offer-price-customer-copy">' . get_option( 'wcj_offer_price_customer_copy', __( 'Send a copy to your email', 'woocommerce-jetpack' ) ) .
|
||||
'</label>' . ' ' .
|
||||
'<input type="checkbox" id="wcj-offer-price-customer-copy" name="wcj-offer-price-customer-copy" value="yes">';
|
||||
// Content
|
||||
$offer_form_content = '<div class="wcj-offer-price-modal-body">' .
|
||||
'<form method="post" id="wcj-offer-price-form">' .
|
||||
'<p>' . $offer_form_content_price . '</p>' .
|
||||
'<p>' . $offer_form_content_email . '</p>' .
|
||||
'<p>' . $offer_form_content_name . '</p>' .
|
||||
'<p>' . $offer_form_content_message . '</p>' .
|
||||
'<p>' . $offer_form_content_button . '</p>' .
|
||||
'<p>' . $offer_form_content_copy . '</p>' .
|
||||
'<input type="hidden" id="wcj-offer-price-product-id" name="wcj-offer-price-product-id">' .
|
||||
'<input type="hidden" name="wcj-offer-price-customer-id" value="' . $customer_id . '">' .
|
||||
'</form>' .
|
||||
'</div>';
|
||||
// Final form
|
||||
echo '<div id="wcj-offer-price-modal" class="wcj-offer-price-modal">' .
|
||||
'<div class="wcj-offer-price-modal-content">' .
|
||||
$offer_form_header .
|
||||
$offer_form_content .
|
||||
$offer_form_footer .
|
||||
'</div>' .
|
||||
'</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* add_offer_price_button.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function add_offer_price_button() {
|
||||
$product_id = get_the_ID();
|
||||
// Check if enabled for current product
|
||||
if ( ! $this->is_offer_price_enabled_for_product( $product_id ) ) {
|
||||
return;
|
||||
}
|
||||
// The button
|
||||
if ( '' != $additional_class = get_option( 'wcj_offer_price_button_class', 'button' ) ) {
|
||||
$additional_class = ' ' . $additional_class;
|
||||
}
|
||||
echo '<p>' .
|
||||
'<button type="submit"' .
|
||||
' name="wcj-offer-price-button"' .
|
||||
' class="wcj-offer-price-button' . $additional_class . '"' .
|
||||
' value="' . $product_id . '"' .
|
||||
' style="' . get_option( 'wcj_offer_price_button_style', '' ) . '"' .
|
||||
' wcj_data=\'' . json_encode( $this->get_wcj_data_array( $product_id ) ) . '\'' .
|
||||
'>' .
|
||||
get_option( 'wcj_offer_price_button_label', __( 'Make an offer', 'woocommerce-jetpack' ) ) .
|
||||
'</button>' .
|
||||
'</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* offer_price.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) separate customer copy email template and subject
|
||||
* @todo (maybe) redirect (no notice though)
|
||||
* @todo (maybe) `%product_title%` etc. in notice
|
||||
* @todo (maybe) fix "From" header
|
||||
* @todo (maybe) check if mail has really been sent
|
||||
* @todo (maybe) sanitize $_POST
|
||||
*/
|
||||
function offer_price() {
|
||||
if ( isset( $_POST['wcj-offer-price-submit'] ) ) {
|
||||
$product_id = $_POST['wcj-offer-price-product-id'];
|
||||
$_product = wc_get_product( $product_id );
|
||||
// Email address
|
||||
$email_address = get_option( 'wcj_offer_price_email_address', '%admin_email%' );
|
||||
if ( '' == $email_address ) {
|
||||
$email_address = get_option( 'admin_email' );
|
||||
} else {
|
||||
$admin_email = get_option( 'admin_email' );
|
||||
if (
|
||||
( $product_author_id = get_post_field( 'post_author', $product_id ) ) &&
|
||||
( $product_user_info = get_userdata( $product_author_id ) ) &&
|
||||
isset( $product_user_info->user_email )
|
||||
) {
|
||||
$product_author_email = $product_user_info->user_email;
|
||||
} else {
|
||||
$product_author_email = $admin_email;
|
||||
}
|
||||
$email_address = str_replace( array( '%admin_email%', '%product_author_email%' ), array( $admin_email, $product_author_email ), $email_address );
|
||||
}
|
||||
// Price offer array
|
||||
$price_offer = array(
|
||||
'offer_timestamp' => current_time( 'timestamp' ),
|
||||
'product_title' => $_product->get_title(),
|
||||
'offered_price' => $_POST['wcj-offer-price-price'],
|
||||
'currency_code' => get_woocommerce_currency(),
|
||||
'customer_message' => $_POST['wcj-offer-price-message'],
|
||||
'customer_name' => $_POST['wcj-offer-price-customer-name'],
|
||||
'customer_email' => $_POST['wcj-offer-price-customer-email'],
|
||||
'customer_id' => $_POST['wcj-offer-price-customer-id'],
|
||||
'copy_to_customer' => ( isset( $_POST['wcj-offer-price-customer-copy'] ) ? $_POST['wcj-offer-price-customer-copy'] : 'no' ),
|
||||
'sent_to' => $email_address,
|
||||
);
|
||||
// Email content
|
||||
$email_template = get_option( 'wcj_offer_price_email_template',
|
||||
sprintf( __( 'Product: %s', 'woocommerce-jetpack' ), '%product_title%' ) . '<br>' . PHP_EOL .
|
||||
sprintf( __( 'Offered price: %s', 'woocommerce-jetpack' ), '%offered_price%' ) . '<br>' . PHP_EOL .
|
||||
sprintf( __( 'From: %s %s', 'woocommerce-jetpack' ), '%customer_name%', '%customer_email%' ) . '<br>' . PHP_EOL .
|
||||
sprintf( __( 'Message: %s', 'woocommerce-jetpack' ), '%customer_message%' )
|
||||
);
|
||||
$replaced_values = array(
|
||||
'%product_title%' => $price_offer['product_title'],
|
||||
'%offered_price%' => wc_price( $price_offer['offered_price'] ),
|
||||
'%customer_message%' => $price_offer['customer_message'],
|
||||
'%customer_name%' => $price_offer['customer_name'],
|
||||
'%customer_email%' => $price_offer['customer_email'],
|
||||
);
|
||||
$email_content = str_replace( array_keys( $replaced_values ), array_values( $replaced_values ), $email_template );
|
||||
// Email subject and headers
|
||||
$email_subject = get_option( 'wcj_offer_price_email_subject', __( 'Price Offer', 'woocommerce-jetpack' ) );
|
||||
$email_headers = 'Content-Type: text/html' . "\r\n" .
|
||||
'From: ' . $price_offer['customer_name'] . ' <' . $price_offer['customer_email'] . '>' . "\r\n" .
|
||||
'Reply-To: ' . $price_offer['customer_email'] . "\r\n";
|
||||
// Send email
|
||||
wc_mail( $email_address, $email_subject, $email_content, $email_headers );
|
||||
if ( 'yes' === $price_offer['copy_to_customer'] ) {
|
||||
wc_mail( $price_offer['customer_email'], $email_subject, $email_content, $email_headers );
|
||||
}
|
||||
// Notice
|
||||
wc_add_notice( get_option( 'wcj_offer_price_customer_notice', __( 'Your price offer has been sent.', 'woocommerce-jetpack' ) ), 'notice' );
|
||||
// Product meta (Offer Price History)
|
||||
if ( '' == ( $price_offers = get_post_meta( $product_id, '_' . 'wcj_price_offers', true ) ) ) {
|
||||
$price_offers = array();
|
||||
}
|
||||
$price_offers[] = $price_offer;
|
||||
update_post_meta( $product_id, '_' . 'wcj_price_offers', $price_offers );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Offer_Price();
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Old Slugs
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Old_Slugs' ) ) :
|
||||
|
||||
class WCJ_Old_Slugs extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'old_slugs';
|
||||
$this->short_desc = __( 'Old Slugs', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Remove old products slugs.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-remove-old-products-slugs';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'old_slugs' => array(
|
||||
'title' => __( 'Remove Old Slugs', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Tool removes old slugs/permalinks from database.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* create_old_slugs_tool.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function create_old_slugs_tool() {
|
||||
global $wpdb;
|
||||
$wp_postmeta_table = $wpdb->prefix . 'postmeta';
|
||||
$all_old_slugs = $wpdb->get_results( "SELECT * FROM $wp_postmeta_table WHERE meta_key = '_wp_old_slug' ORDER BY post_id" );
|
||||
$num_old_slugs = count( $all_old_slugs );
|
||||
$remove_result_html = '';
|
||||
$headings = array(
|
||||
__( 'Old slug', 'woocommerce-jetpack' ),
|
||||
__( 'Post title', 'woocommerce-jetpack' ),
|
||||
__( 'Post id', 'woocommerce-jetpack' ),
|
||||
__( 'Post type', 'woocommerce-jetpack' ),
|
||||
__( 'Current slug', 'woocommerce-jetpack' ),
|
||||
);
|
||||
$multi_table_data = array(
|
||||
'products' => array( $headings ),
|
||||
'non_products' => array( $headings ),
|
||||
);
|
||||
$posts_ids = array(
|
||||
'products' => array(),
|
||||
'non_products' => array(),
|
||||
);
|
||||
if ( $num_old_slugs > 0 ) {
|
||||
// Fill `multi_table_data` and `posts_ids`
|
||||
foreach ( $all_old_slugs as $old_slug_object ) {
|
||||
$slug_post_type = get_post_type( $old_slug_object->post_id );
|
||||
$current_slug = get_post( $old_slug_object->post_id )->post_name;
|
||||
$type = ( in_array( $slug_post_type, array( 'product', 'product_variation' ) ) ) ? 'products' : 'non_products';
|
||||
$multi_table_data[ $type ][] = array(
|
||||
'<strong>' . $old_slug_object->meta_value . '</strong>',
|
||||
get_the_title( $old_slug_object->post_id ),
|
||||
$old_slug_object->post_id,
|
||||
$slug_post_type,
|
||||
$current_slug,
|
||||
);
|
||||
$posts_ids[ $type ][] = $old_slug_object->post_id;
|
||||
}
|
||||
// Actions
|
||||
if ( isset( $_POST['remove_old_products_slugs'] ) || isset( $_POST['remove_old_non_products_slugs'] ) ) {
|
||||
$post_ids_to_delete = join( ',', ( isset( $_POST['remove_old_products_slugs'] ) ? $posts_ids['products'] : $posts_ids['non_products'] ) );
|
||||
$delete_result = $wpdb->get_results( "DELETE FROM $wp_postmeta_table WHERE meta_key = '_wp_old_slug' AND post_id IN ($post_ids_to_delete)" );
|
||||
$recheck_result = $wpdb->get_results( "SELECT * FROM $wp_postmeta_table WHERE meta_key = '_wp_old_slug'" );
|
||||
$recheck_result_count = count( $recheck_result );
|
||||
$remove_result_html = '<div class="updated"><p>' .
|
||||
sprintf(
|
||||
__( 'Removing old slugs from database finished! <strong>%d</strong> old slug(s) deleted.', 'woocommerce-jetpack' ),
|
||||
( $num_old_slugs - $recheck_result_count )
|
||||
) . ' ' . __( 'Please <a href="">refresh</a> the page.', 'woocommerce-jetpack' ) .
|
||||
'</p></div>';
|
||||
}
|
||||
}
|
||||
$this->output_old_slugs_tool( $remove_result_html, $multi_table_data, $num_old_slugs, $posts_ids );
|
||||
}
|
||||
|
||||
/**
|
||||
* output_old_slugs_tool.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function output_old_slugs_tool( $remove_result_html, $multi_table_data, $num_old_slugs, $posts_ids ) {
|
||||
$html = '';
|
||||
$html .= '<div class="wrap">';
|
||||
$html .= $this->get_tool_header_html( 'old_slugs' );
|
||||
$html .= $remove_result_html;
|
||||
$types = array(
|
||||
'products' => array(
|
||||
'table_heading' => __( 'Old products slugs found:', 'woocommerce-jetpack' ),
|
||||
'table_content' => wcj_get_table_html( $multi_table_data['products'], array( 'table_class' => 'widefat striped' ) ),
|
||||
'button_name' => 'remove_old_products_slugs',
|
||||
'button_label' => __( 'Remove all old product slugs', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'non_products' => array(
|
||||
'table_heading' => __( 'Old non-products slugs found:', 'woocommerce-jetpack' ),
|
||||
'table_content' => wcj_get_table_html( $multi_table_data['non_products'], array( 'table_class' => 'widefat striped' ) ),
|
||||
'button_name' => 'remove_old_non_products_slugs',
|
||||
'button_label' => __( 'Remove all old non-product slugs', 'woocommerce-jetpack' ),
|
||||
),
|
||||
);
|
||||
foreach ( $types as $type_id => $type ) {
|
||||
$_num_old_slugs = isset( $posts_ids[ $type_id ] ) ? count( $posts_ids[ $type_id ] ) : 0;
|
||||
if ( $_num_old_slugs > 0 ) {
|
||||
$html .= '<h4>' . $type['table_heading'] . ' ' . $_num_old_slugs . '</h4>';
|
||||
$html .= '<p>' . $type['table_content'] . '</p>';
|
||||
$html .= '<form method="post" action="">';
|
||||
$html .= '<input class="button-primary" type="submit" name="' . $type['button_name'] . '" value="' . $type['button_label'] . '"/>';
|
||||
$html .= '</form>';
|
||||
}
|
||||
}
|
||||
if ( $num_old_slugs == 0 ) {
|
||||
$html .= '<div class="updated"><p><strong>' . __( 'No old slugs found.', 'woocommerce-jetpack' ) . '</strong></p></div>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
echo $html;
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Old_Slugs();
|
||||
@@ -0,0 +1,343 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Order Custom Statuses
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Order_Custom_Statuses' ) ) :
|
||||
|
||||
class WCJ_Order_Custom_Statuses extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @todo check all changes from Custom Order Status plugin
|
||||
* @todo `wcj_orders_custom_statuses_processing_and_completed_actions` to Custom Order Status plugin
|
||||
* @todo (maybe) add options to change icon and icon's color for all statuses (i.e. not only custom)
|
||||
* @todo (maybe) rename module to "Custom Order Statuses"
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'order_custom_statuses';
|
||||
$this->short_desc = __( 'Order Custom Statuses', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Custom statuses for WooCommerce orders.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-order-custom-statuses';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'custom_statuses' => array(
|
||||
'title' => __( 'Custom Statuses', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Tool lets you add, edit or delete any custom status for WooCommerce orders.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
add_filter( 'wc_order_statuses', array( $this, 'add_custom_statuses_to_filter' ), PHP_INT_MAX );
|
||||
add_action( 'init', array( $this, 'register_custom_post_statuses' ) );
|
||||
add_action( 'admin_head', array( $this, 'hook_statuses_icons_css' ) );
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_column_colored', 'no' ) ) ) {
|
||||
add_action( 'admin_head', array( $this, 'hook_statuses_column_css' ) );
|
||||
}
|
||||
|
||||
add_filter( 'woocommerce_default_order_status', array( $this, 'set_default_order_status' ), PHP_INT_MAX );
|
||||
|
||||
if ( 'yes' === get_option( 'wcj_orders_custom_statuses_add_to_reports' ) ) {
|
||||
add_filter( 'woocommerce_reports_order_statuses', array( $this, 'add_custom_order_statuses_to_reports' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
if ( 'yes' === get_option( 'wcj_orders_custom_statuses_add_to_bulk_actions' ) ) {
|
||||
add_action( 'admin_footer', array( $this, 'bulk_admin_footer' ), 11 );
|
||||
}
|
||||
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_add_to_order_list_actions', 'no' ) ) ) {
|
||||
add_filter( 'woocommerce_admin_order_actions', array( $this, 'add_custom_status_actions_buttons' ), PHP_INT_MAX, 2 );
|
||||
add_action( 'admin_head', array( $this, 'add_custom_status_actions_buttons_css' ) );
|
||||
}
|
||||
|
||||
if ( 'hide' != apply_filters( 'booster_option', 'hide', get_option( 'wcj_orders_custom_statuses_processing_and_completed_actions', 'hide' ) ) ) {
|
||||
add_filter( 'woocommerce_admin_order_actions', array( $this, 'add_custom_status_to_processing_and_completed_actions' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
// Is order editable
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_is_order_editable', 'no' ) ) ) {
|
||||
add_filter( 'wc_order_is_editable', array( $this, 'add_custom_order_statuses_to_order_editable' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
// "Order Statuses" tool
|
||||
include_once( 'tools/class-wcj-order-statuses-tool.php' );
|
||||
$this->custom_statuses_tool = new WCJ_Order_Statuses_Tool( 'custom_statuses', $this );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_custom_order_statuses.
|
||||
*
|
||||
* @version 3.1.2
|
||||
* @since 3.1.2
|
||||
*/
|
||||
function get_custom_order_statuses( $cut_prefix = false ) {
|
||||
$orders_custom_statuses = get_option( 'wcj_orders_custom_statuses_array', '' );
|
||||
if ( empty( $orders_custom_statuses ) ) {
|
||||
return array();
|
||||
} else {
|
||||
if ( $cut_prefix ) {
|
||||
$orders_custom_statuses_no_prefix = array();
|
||||
foreach( $orders_custom_statuses as $status => $status_name ) {
|
||||
$orders_custom_statuses_no_prefix[ substr( $status, 3 ) ] = $status_name;
|
||||
}
|
||||
return $orders_custom_statuses_no_prefix;
|
||||
} else {
|
||||
return $orders_custom_statuses;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_order_statuses_to_order_editable.
|
||||
*
|
||||
* @version 3.1.2
|
||||
* @since 3.1.2
|
||||
*/
|
||||
function add_custom_order_statuses_to_order_editable( $is_editable, $_order ) {
|
||||
return ( in_array( $_order->get_status(), array_keys( $this->get_custom_order_statuses( true ) ) ) ? true : $is_editable );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_status_to_processing_and_completed_actions.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function add_custom_status_to_processing_and_completed_actions( $actions, $_order ) {
|
||||
$custom_order_statuses = $this->get_custom_order_statuses();
|
||||
if ( ! empty( $custom_order_statuses ) && is_array( $custom_order_statuses ) ) {
|
||||
$custom_order_statuses_without_wc_prefix = array();
|
||||
foreach ( $custom_order_statuses as $slug => $label ) {
|
||||
$custom_order_statuses_without_wc_prefix[] = substr( $slug, 3 );
|
||||
}
|
||||
global $post;
|
||||
$default_actions = array();
|
||||
$show = apply_filters( 'booster_option', 'hide', get_option( 'wcj_orders_custom_statuses_processing_and_completed_actions', 'hide' ) );
|
||||
if (
|
||||
( 'show_both' === $show || 'show_processing' === $show ) &&
|
||||
$_order->has_status( array_merge( array( 'pending', 'on-hold' ), $custom_order_statuses_without_wc_prefix ) )
|
||||
) {
|
||||
$default_actions['processing'] = array(
|
||||
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=processing&order_id=' . $post->ID ),
|
||||
'woocommerce-mark-order-status' ),
|
||||
'name' => __( 'Processing', 'woocommerce' ),
|
||||
'action' => "processing",
|
||||
);
|
||||
}
|
||||
if (
|
||||
( 'show_both' === $show || 'show_complete' === $show ) &&
|
||||
$_order->has_status( array_merge( array( 'pending', 'on-hold', 'processing' ), $custom_order_statuses_without_wc_prefix ) )
|
||||
) {
|
||||
$default_actions['complete'] = array(
|
||||
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=completed&order_id=' . $post->ID ),
|
||||
'woocommerce-mark-order-status' ),
|
||||
'name' => __( 'Complete', 'woocommerce' ),
|
||||
'action' => "complete",
|
||||
);
|
||||
}
|
||||
$actions = array_merge( $default_actions, $actions );
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_status_actions_buttons.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function add_custom_status_actions_buttons( $actions, $_order ) {
|
||||
$custom_order_statuses = $this->get_custom_order_statuses();
|
||||
if ( ! empty( $custom_order_statuses ) && is_array( $custom_order_statuses ) ) {
|
||||
foreach ( $custom_order_statuses as $slug => $label ) {
|
||||
$custom_order_status = substr( $slug, 3 );
|
||||
if ( ! $_order->has_status( array( $custom_order_status ) ) ) { // if order status is not $custom_order_status
|
||||
$actions[ $custom_order_status ] = array(
|
||||
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=' . $custom_order_status . '&order_id=' .
|
||||
wcj_get_order_id( $_order ) ), 'woocommerce-mark-order-status' ),
|
||||
'name' => $label,
|
||||
'action' => "view " . $custom_order_status, // setting "view" for proper button CSS
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_status_icon_data.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.2.2
|
||||
*/
|
||||
function get_status_icon_data( $status_slug_without_wc_prefix ) {
|
||||
$return = array(
|
||||
'content' => 'e011',
|
||||
'color' => '#999999',
|
||||
'text_color' => '#000000',
|
||||
);
|
||||
if ( '' != ( $icon_data = get_option( 'wcj_orders_custom_status_icon_data_' . $status_slug_without_wc_prefix, '' ) ) ) {
|
||||
$return['content'] = $icon_data['content'];
|
||||
$return['color'] = $icon_data['color'];
|
||||
if ( isset( $icon_data['text_color'] ) ) {
|
||||
$return['text_color'] = $icon_data['text_color'];
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_status_actions_buttons_css.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function add_custom_status_actions_buttons_css() {
|
||||
$custom_order_statuses = $this->get_custom_order_statuses( true );
|
||||
foreach ( $custom_order_statuses as $slug => $label ) {
|
||||
$icon_data = $this->get_status_icon_data( $slug );
|
||||
$color_style = ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_add_to_order_list_actions_colored', 'no' ) ) ) ?
|
||||
' color: ' . $icon_data['color'] . ' !important;' : '';
|
||||
echo '<style>.view.' . $slug . '::after { font-family: WooCommerce !important;' . $color_style .
|
||||
' content: "\\' . $icon_data['content'] . '" !important; }</style>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_order_statuses_to_reports.
|
||||
*
|
||||
* @version 3.2.2
|
||||
*/
|
||||
function add_custom_order_statuses_to_reports( $order_statuses ) {
|
||||
if ( is_array( $order_statuses ) && in_array( 'completed', $order_statuses ) ) {
|
||||
return array_merge( $order_statuses, array_keys( $this->get_custom_order_statuses( true ) ) );
|
||||
} else {
|
||||
return $order_statuses;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set_default_order_status.
|
||||
*
|
||||
* @version 3.2.2
|
||||
*/
|
||||
function set_default_order_status( $status ) {
|
||||
return ( 'wcj_no_changes' != ( $default_status = get_option( 'wcj_orders_custom_statuses_default_status', 'pending' ) ) ? $default_status : $status );
|
||||
}
|
||||
|
||||
/**
|
||||
* register_custom_post_statuses.
|
||||
*
|
||||
* @version 3.2.2
|
||||
*/
|
||||
function register_custom_post_statuses() {
|
||||
$custom_statuses = $this->get_custom_order_statuses();
|
||||
foreach ( $custom_statuses as $slug => $label )
|
||||
register_post_status( $slug, array(
|
||||
'label' => $label,
|
||||
'public' => true,
|
||||
'exclude_from_search' => false,
|
||||
'show_in_admin_all_list' => true,
|
||||
'show_in_admin_status_list' => true,
|
||||
'label_count' => _n_noop( $label . ' <span class="count">(%s)</span>', $label . ' <span class="count">(%s)</span>' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_statuses_to_filter.
|
||||
*
|
||||
* @version 3.2.2
|
||||
*/
|
||||
function add_custom_statuses_to_filter( $order_statuses ) {
|
||||
return array_merge( ( '' == $order_statuses ? array() : $order_statuses ), $this->get_custom_order_statuses() );
|
||||
}
|
||||
|
||||
/**
|
||||
* hook_statuses_column_css.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function hook_statuses_column_css() {
|
||||
$output = '';
|
||||
$statuses = $this->get_custom_order_statuses( true );
|
||||
foreach( $statuses as $status => $status_name ) {
|
||||
$icon_data = $this->get_status_icon_data( $status );
|
||||
$output .= 'mark.order-status.status-' . $status . ' { color: ' . $icon_data['text_color'] . '; background-color: ' . $icon_data['color'] . '; }';
|
||||
}
|
||||
if ( '' != $output ) {
|
||||
echo '<style>' . $output . '</style>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hook_statuses_icons_css.
|
||||
*
|
||||
* @version 3.2.2
|
||||
*/
|
||||
function hook_statuses_icons_css() {
|
||||
$output = '';
|
||||
$statuses = $this->get_custom_order_statuses( true );
|
||||
foreach( $statuses as $status => $status_name ) {
|
||||
$icon_data = $this->get_status_icon_data( $status );
|
||||
$output .= 'mark.' . $status . '::after { content: "\\' . $icon_data['content'] . '"; color: ' . $icon_data['color'] . '; }';
|
||||
$output .= 'mark.' . $status . ':after {font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;' .
|
||||
'line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}';
|
||||
}
|
||||
if ( '' != $output ) {
|
||||
echo '<style>' . $output . '</style>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create_custom_statuses_tool.
|
||||
*
|
||||
* @version 3.2.2
|
||||
*/
|
||||
function create_custom_statuses_tool() {
|
||||
return $this->custom_statuses_tool->create_tool();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra bulk action options to mark orders as complete or processing
|
||||
*
|
||||
* Using Javascript until WordPress core fixes: http://core.trac.wordpress.org/ticket/16031
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.2.7
|
||||
*/
|
||||
function bulk_admin_footer() {
|
||||
global $post_type;
|
||||
if ( 'shop_order' == $post_type ) {
|
||||
?><script type="text/javascript"><?php
|
||||
foreach( wcj_get_order_statuses() as $key => $order_status ) {
|
||||
if ( in_array( $key, array( 'processing', 'on-hold', 'completed', ) ) ) continue;
|
||||
?>jQuery(function() {
|
||||
jQuery('<option>').val('mark_<?php echo $key; ?>').text('<?php echo __( 'Mark', 'woocommerce-jetpack' ) . ' ' .
|
||||
$order_status; ?>').appendTo('select[name="action"]');
|
||||
jQuery('<option>').val('mark_<?php echo $key; ?>').text('<?php echo __( 'Mark', 'woocommerce-jetpack' ) . ' ' .
|
||||
$order_status; ?>').appendTo('select[name="action2"]');
|
||||
});<?php
|
||||
}
|
||||
?></script><?php
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Order_Custom_Statuses();
|
||||
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Order Minimum Amount
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.5.7
|
||||
* @author Algoritmika Ltd.
|
||||
* @todo order max amount
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Order_Min_Amount' ) ) :
|
||||
|
||||
class WCJ_Order_Min_Amount extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'order_min_amount';
|
||||
$this->short_desc = __( 'Order Minimum Amount', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Minimum order amount (optionally by user role).', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-order-minimum-amount';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'init', array( $this, 'add_order_minimum_amount_hooks' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_order_minimum_amount_hooks.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.5.3
|
||||
* @todo (maybe) `template_redirect` instead of `wp`
|
||||
*/
|
||||
function add_order_minimum_amount_hooks() {
|
||||
$is_order_minimum_amount_enabled = false;
|
||||
if ( get_option( 'wcj_order_minimum_amount', 0 ) > 0 ) {
|
||||
$is_order_minimum_amount_enabled = true;
|
||||
} else {
|
||||
foreach ( wcj_get_user_roles() as $role_key => $role_data ) {
|
||||
if ( get_option( 'wcj_order_minimum_amount_by_user_role_' . $role_key, 0 ) > 0 ) {
|
||||
$is_order_minimum_amount_enabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $is_order_minimum_amount_enabled ) {
|
||||
add_action( 'woocommerce_checkout_process', array( $this, 'order_minimum_amount' ) );
|
||||
add_action( 'woocommerce_before_cart', array( $this, 'order_minimum_amount' ) );
|
||||
if ( 'yes' === get_option( 'wcj_order_minimum_amount_stop_from_seeing_checkout', 'no' ) ) {
|
||||
add_action( 'wp', array( $this, 'stop_from_seeing_checkout' ), 100 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_order_minimum_amount_with_user_roles.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function get_order_minimum_amount_with_user_roles() {
|
||||
$minimum = get_option( 'wcj_order_minimum_amount', 0 );
|
||||
$current_user_role = wcj_get_current_user_first_role();
|
||||
foreach ( wcj_get_user_roles() as $role_key => $role_data ) {
|
||||
if ( $role_key === $current_user_role ) {
|
||||
$order_minimum_amount_by_user_role = get_option( 'wcj_order_minimum_amount_by_user_role_' . $role_key, 0 );
|
||||
if ( $order_minimum_amount_by_user_role > /* $minimum */ 0 ) {
|
||||
$minimum = $order_minimum_amount_by_user_role;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Multicurrency (Currency Switcher) module
|
||||
if ( WCJ()->modules['multicurrency']->is_enabled() ) {
|
||||
$minimum = WCJ()->modules['multicurrency']->change_price( $minimum, null );
|
||||
}
|
||||
return $minimum;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_cart_total_for_minimal_order_amount.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.5.5
|
||||
*/
|
||||
function get_cart_total_for_minimal_order_amount() {
|
||||
if ( ! isset( WC()->cart ) ) {
|
||||
return 0;
|
||||
}
|
||||
WC()->cart->calculate_totals();
|
||||
$cart_total = WC()->cart->total;
|
||||
if ( 'yes' === get_option( 'wcj_order_minimum_amount_exclude_shipping', 'no' ) ) {
|
||||
$shipping_total = isset( WC()->cart->shipping_total ) ? WC()->cart->shipping_total : 0;
|
||||
$shipping_tax_total = isset( WC()->cart->shipping_tax_total ) ? WC()->cart->shipping_tax_total : 0;
|
||||
$cart_total -= ( $shipping_total + $shipping_tax_total );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_order_minimum_amount_exclude_discounts', 'no' ) ) {
|
||||
$cart_total += ( WC()->cart->get_cart_discount_total() + WC()->cart->get_cart_discount_tax_total() );
|
||||
}
|
||||
return $cart_total;
|
||||
}
|
||||
|
||||
/**
|
||||
* order_minimum_amount.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @todo `wcj_order_minimum_amount_checkout_notice_type`
|
||||
*/
|
||||
function order_minimum_amount() {
|
||||
$minimum = $this->get_order_minimum_amount_with_user_roles();
|
||||
if ( 0 == $minimum ) {
|
||||
return;
|
||||
}
|
||||
$cart_total = $this->get_cart_total_for_minimal_order_amount();
|
||||
if ( $cart_total < $minimum ) {
|
||||
if ( is_cart() ) {
|
||||
if ( 'yes' === get_option( 'wcj_order_minimum_amount_cart_notice_enabled', 'no' ) ) {
|
||||
$notice_function = get_option( 'wcj_order_minimum_amount_cart_notice_function', 'wc_print_notice' );
|
||||
$notice_function(
|
||||
sprintf( apply_filters( 'booster_option', 'You must have an order with a minimum of %s to place your order, your current order total is %s.', get_option( 'wcj_order_minimum_amount_cart_notice_message' ) ),
|
||||
wc_price( $minimum ),
|
||||
wc_price( $cart_total )
|
||||
),
|
||||
get_option( 'wcj_order_minimum_amount_cart_notice_type', 'notice' )
|
||||
);
|
||||
}
|
||||
} else {
|
||||
wc_add_notice(
|
||||
sprintf( apply_filters( 'booster_option', 'You must have an order with a minimum of %s to place your order, your current order total is %s.', get_option( 'wcj_order_minimum_amount_error_message' ) ),
|
||||
wc_price( $minimum ),
|
||||
wc_price( $cart_total )
|
||||
),
|
||||
'error'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* stop_from_seeing_checkout.
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @todo (maybe) `if ( is_admin() ) return;`
|
||||
*/
|
||||
function stop_from_seeing_checkout( $wp ) {
|
||||
global $woocommerce;
|
||||
if ( ! isset( $woocommerce ) || ! is_object( $woocommerce ) ) {
|
||||
return;
|
||||
}
|
||||
if ( ! isset( $woocommerce->cart ) || ! is_object( $woocommerce->cart ) ) {
|
||||
return;
|
||||
}
|
||||
if ( ! is_checkout() ) {
|
||||
return;
|
||||
}
|
||||
$minimum = $this->get_order_minimum_amount_with_user_roles();
|
||||
if ( 0 == $minimum ) {
|
||||
return;
|
||||
}
|
||||
$the_cart_total = $this->get_cart_total_for_minimal_order_amount();
|
||||
if ( 0 == $the_cart_total ) {
|
||||
return;
|
||||
}
|
||||
if ( $the_cart_total < $minimum ) {
|
||||
wp_safe_redirect( wc_get_cart_url() );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Order_Min_Amount();
|
||||
@@ -0,0 +1,360 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Order Numbers
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Order_Numbers' ) ) :
|
||||
|
||||
class WCJ_Order_Numbers extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @todo (maybe) rename "Orders Renumerate" to "Renumerate orders"
|
||||
* @todo (maybe) use `woocommerce_new_order` hook instead of `wp_insert_post`
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'order_numbers';
|
||||
$this->short_desc = __( 'Order Numbers', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Sequential order numbering, custom order number prefix, suffix and number width.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-custom-order-numbers';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'renumerate_orders' => array(
|
||||
'title' => __( 'Orders Renumerate', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Tool renumerates all orders.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'wp_insert_post', array( $this, 'add_new_order_number' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_order_number', array( $this, 'display_order_number' ), PHP_INT_MAX, 2 );
|
||||
if ( 'yes' === get_option( 'wcj_order_number_order_tracking_enabled', 'yes' ) ) {
|
||||
add_filter( 'woocommerce_shortcode_order_tracking_order_id', array( $this, 'add_order_number_to_tracking' ), PHP_INT_MAX );
|
||||
add_action( 'init', array( $this, 'remove_order_tracking_sanitize_order_id_filter' ) );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_order_number_search_by_custom_number_enabled', 'yes' ) ) {
|
||||
add_action( 'pre_get_posts', array( $this, 'search_by_custom_number' ) );
|
||||
}
|
||||
// "WooCommerce Subscriptions" plugin
|
||||
$woocommerce_subscriptions_types = array( 'subscription', 'renewal_order', 'resubscribe_order', 'copy_order' );
|
||||
foreach ( $woocommerce_subscriptions_types as $woocommerce_subscriptions_type ) {
|
||||
add_filter( 'wcs_' . $woocommerce_subscriptions_type . '_meta', array( $this, 'woocommerce_subscriptions_remove_meta_copy' ), PHP_INT_MAX, 3 );
|
||||
}
|
||||
// Editable order number
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_number_editable_order_number_meta_box_enabled', 'no' ) ) ) {
|
||||
$this->meta_box_screen = 'shop_order';
|
||||
$this->meta_box_context = 'side';
|
||||
$this->meta_box_priority = 'high';
|
||||
add_action( 'add_meta_boxes', array( $this, 'maybe_add_meta_box' ), PHP_INT_MAX, 2 );
|
||||
add_action( 'save_post_shop_order', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_meta_box.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
* @todo re-think if setting number for yet not-numbered order should be allowed (i.e. do not check for `( '' !== get_post_meta( $post->ID, '_wcj_order_number', true ) )`)
|
||||
*/
|
||||
function maybe_add_meta_box( $post_type, $post ) {
|
||||
if ( '' !== get_post_meta( $post->ID, '_wcj_order_number', true ) ) {
|
||||
parent::add_meta_box();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* woocommerce_subscriptions_remove_meta_copy.
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @since 3.2.3
|
||||
*/
|
||||
function woocommerce_subscriptions_remove_meta_copy( $meta, $to_order, $from_order ) {
|
||||
foreach ( $meta as $meta_id => $meta_item ) {
|
||||
if ( '_wcj_order_number' === $meta_item['meta_key'] ) {
|
||||
unset( $meta[ $meta_id ] );
|
||||
}
|
||||
}
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove_order_tracking_sanitize_order_id_filter.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function remove_order_tracking_sanitize_order_id_filter() {
|
||||
remove_filter( 'woocommerce_shortcode_order_tracking_order_id', 'wc_sanitize_order_id' );
|
||||
}
|
||||
|
||||
/**
|
||||
* search_by_custom_number.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
* @see https://github.com/pablo-pacheco/wc-booster-search-order-by-custom-number-fix
|
||||
* @todo `_wcj_order_number` is used for `sequential` and `hash` only
|
||||
*/
|
||||
function search_by_custom_number( $query ) {
|
||||
if (
|
||||
! is_admin() ||
|
||||
! isset( $query->query ) ||
|
||||
! isset( $query->query['s'] ) ||
|
||||
false === is_numeric( $query->query['s'] ) ||
|
||||
0 == $query->query['s'] ||
|
||||
'shop_order' !== $query->query['post_type'] ||
|
||||
! $query->query_vars['shop_order_search']
|
||||
) {
|
||||
return;
|
||||
}
|
||||
$custom_order_id = $query->query['s'];
|
||||
$query->query_vars['post__in'] = array();
|
||||
$query->query['s'] = '';
|
||||
$query->set( 'meta_key', '_wcj_order_number' );
|
||||
$query->set( 'meta_value', $custom_order_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_order_number_to_tracking.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_order_number_to_tracking( $order_number ) {
|
||||
$offset = 0;
|
||||
$block_size = 512;
|
||||
while( true ) {
|
||||
$args = array(
|
||||
'post_type' => 'shop_order',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => $block_size,
|
||||
'orderby' => 'ID',
|
||||
'order' => 'DESC',
|
||||
'offset' => $offset,
|
||||
'fields' => 'ids',
|
||||
);
|
||||
$loop = new WP_Query( $args );
|
||||
if ( ! $loop->have_posts() ) {
|
||||
break;
|
||||
}
|
||||
foreach ( $loop->posts as $_order_id ) {
|
||||
$_order = wc_get_order( $_order_id );
|
||||
$_order_number = $this->display_order_number( $_order_id, $_order );
|
||||
if ( $_order_number === $order_number ) {
|
||||
return $_order_id;
|
||||
}
|
||||
}
|
||||
$offset += $block_size;
|
||||
}
|
||||
return $order_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display order number.
|
||||
*
|
||||
* @version 3.5.0
|
||||
*/
|
||||
function display_order_number( $order_number, $order ) {
|
||||
$order_id = wcj_get_order_id( $order );
|
||||
$order_number_meta = get_post_meta( $order_id , '_wcj_order_number', true );
|
||||
if ( '' == $order_number_meta || 'no' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
|
||||
$order_number_meta = $order_id;
|
||||
}
|
||||
$order_timestamp = strtotime( ( WCJ_IS_WC_VERSION_BELOW_3 ? $order->post->post_date : $order->get_date_created() ) );
|
||||
$order_number = apply_filters( 'booster_option',
|
||||
sprintf( '%s%s', do_shortcode( get_option( 'wcj_order_number_prefix', '' ) ), $order_number_meta ),
|
||||
sprintf( '%s%s%0' . get_option( 'wcj_order_number_min_width', 0 ) . 's%s%s',
|
||||
do_shortcode( get_option( 'wcj_order_number_prefix', '' ) ),
|
||||
date_i18n( get_option( 'wcj_order_number_date_prefix', '' ), $order_timestamp ),
|
||||
$order_number_meta,
|
||||
do_shortcode( get_option( 'wcj_order_number_suffix', '' ) ),
|
||||
date_i18n( get_option( 'wcj_order_number_date_suffix', '' ), $order_timestamp )
|
||||
)
|
||||
);
|
||||
if ( false !== strpos( $order_number, '%order_items_skus%' ) ) {
|
||||
$order_number = str_replace( '%order_items_skus%', do_shortcode( '[wcj_order_items order_id="' . $order_id . '" field="_sku" sep="-"]' ), $order_number );
|
||||
}
|
||||
return $order_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Renumerate Orders tool to WooCommerce menu (the content).
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @todo restyle
|
||||
* @todo add more result info (e.g. number of regenerated orders etc.)
|
||||
*/
|
||||
function create_renumerate_orders_tool() {
|
||||
$result_message = '';
|
||||
if ( isset( $_POST['renumerate_orders'] ) ) {
|
||||
$this->renumerate_orders();
|
||||
$result_message = '<p><div class="updated"><p><strong>' . __( 'Orders successfully renumerated!', 'woocommerce-jetpack' ) . '</strong></p></div></p>';
|
||||
} else {
|
||||
if ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
|
||||
$result_message .= '<p>' . sprintf( __( 'Sequential number generation is enabled. Next order number will be %s.', 'woocommerce-jetpack' ),
|
||||
'<code>' . get_option( 'wcj_order_number_counter', 1 ) . '</code>' ) . '</p>';
|
||||
}
|
||||
}
|
||||
$html = '';
|
||||
$html .= '<div class="wrap">';
|
||||
$html .= $this->get_tool_header_html( 'renumerate_orders' );
|
||||
$html .= '<p>';
|
||||
$html .= sprintf(
|
||||
__( 'Press the button below to renumerate all existing orders starting from order counter settings in <a href="%s">Order Numbers</a> module.',
|
||||
'woocommerce-jetpack' ),
|
||||
admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=shipping_and_orders§ion=order_numbers' )
|
||||
);
|
||||
$html .= '</p>';
|
||||
$html .= $result_message;
|
||||
$html .= '<form method="post" action="">';
|
||||
$html .= '<input class="button-primary" type="submit" name="renumerate_orders" value="' . __( 'Renumerate orders', 'woocommerce-jetpack' ) . '">';
|
||||
$html .= '</form>';
|
||||
$html .= '</div>';
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_new_order_number.
|
||||
*/
|
||||
function add_new_order_number( $order_id ) {
|
||||
$this->add_order_number_meta( $order_id, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_reset_sequential_counter.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
* @todo use transactions on `wcj_order_number_use_mysql_transaction_enabled`
|
||||
*/
|
||||
function maybe_reset_sequential_counter( $current_order_number, $order_id ) {
|
||||
if ( 'no' != ( $reset_period = get_option( 'wcj_order_number_counter_reset_enabled', 'no' ) ) ) {
|
||||
$previous_order_date = get_option( 'wcj_order_number_counter_previous_order_date', 0 );
|
||||
$current_order_date = strtotime( wcj_get_order_date( wc_get_order( $order_id ) ) );
|
||||
update_option( 'wcj_order_number_counter_previous_order_date', $current_order_date );
|
||||
if ( 0 != $previous_order_date ) {
|
||||
$do_reset = false;
|
||||
switch ( $reset_period ) {
|
||||
case 'daily':
|
||||
$do_reset = (
|
||||
date( 'Y', $current_order_date ) != date( 'Y', $previous_order_date ) ||
|
||||
date( 'm', $current_order_date ) != date( 'm', $previous_order_date ) ||
|
||||
date( 'd', $current_order_date ) != date( 'd', $previous_order_date )
|
||||
);
|
||||
break;
|
||||
case 'monthly':
|
||||
$do_reset = (
|
||||
date( 'Y', $current_order_date ) != date( 'Y', $previous_order_date ) ||
|
||||
date( 'm', $current_order_date ) != date( 'm', $previous_order_date )
|
||||
);
|
||||
break;
|
||||
case 'yearly':
|
||||
$do_reset = (
|
||||
date( 'Y', $current_order_date ) != date( 'Y', $previous_order_date )
|
||||
);
|
||||
break;
|
||||
}
|
||||
if ( $do_reset ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $current_order_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add/update order_number meta to order.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @todo (maybe) save order ID instead of `$current_order_number = ''` (if `'no' === get_option( 'wcj_order_number_sequential_enabled', 'yes' )`)
|
||||
*/
|
||||
function add_order_number_meta( $order_id, $do_overwrite ) {
|
||||
if ( 'shop_order' !== get_post_type( $order_id ) || 'auto-draft' === get_post_status( $order_id ) ) {
|
||||
return;
|
||||
}
|
||||
if ( true === $do_overwrite || 0 == get_post_meta( $order_id, '_wcj_order_number', true ) ) {
|
||||
if ( $order_id < get_option( 'wcj_order_numbers_min_order_id', 0 ) ) {
|
||||
return;
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) && 'yes' === get_option( 'wcj_order_number_use_mysql_transaction_enabled', 'yes' ) ) {
|
||||
global $wpdb;
|
||||
$wpdb->query( 'START TRANSACTION' );
|
||||
$wp_options_table = $wpdb->prefix . 'options';
|
||||
$result_select = $wpdb->get_row( "SELECT * FROM $wp_options_table WHERE option_name = 'wcj_order_number_counter'" );
|
||||
if ( NULL != $result_select ) {
|
||||
$current_order_number = $this->maybe_reset_sequential_counter( $result_select->option_value, $order_id );
|
||||
$result_update = $wpdb->update( $wp_options_table, array( 'option_value' => ( $current_order_number + 1 ) ), array( 'option_name' => 'wcj_order_number_counter' ) );
|
||||
if ( NULL != $result_update || $result_select->option_value == ( $current_order_number + 1 ) ) {
|
||||
$wpdb->query( 'COMMIT' ); // all ok
|
||||
update_post_meta( $order_id, '_wcj_order_number', $current_order_number );
|
||||
} else {
|
||||
$wpdb->query( 'ROLLBACK' ); // something went wrong, Rollback
|
||||
}
|
||||
} else {
|
||||
$wpdb->query( 'ROLLBACK' ); // something went wrong, Rollback
|
||||
}
|
||||
} else {
|
||||
if ( 'hash_crc32' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
|
||||
$current_order_number = sprintf( "%u", crc32( $order_id ) );
|
||||
} elseif ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) ) {
|
||||
$current_order_number = $this->maybe_reset_sequential_counter( get_option( 'wcj_order_number_counter', 1 ), $order_id );
|
||||
update_option( 'wcj_order_number_counter', ( $current_order_number + 1 ) );
|
||||
} else { // 'no' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) // order ID
|
||||
$current_order_number = '';
|
||||
}
|
||||
update_post_meta( $order_id, '_wcj_order_number', $current_order_number );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renumerate orders function.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @todo renumerate in date range only
|
||||
* @todo (maybe) selectable `post_status`
|
||||
* @todo (maybe) set default value for `wcj_order_numbers_renumerate_tool_orderby` to `ID` (instead of `date`)
|
||||
*/
|
||||
function renumerate_orders() {
|
||||
if ( 'yes' === get_option( 'wcj_order_number_sequential_enabled', 'yes' ) && 'no' != get_option( 'wcj_order_number_counter_reset_enabled', 'no' ) ) {
|
||||
update_option( 'wcj_order_number_counter_previous_order_date', 0 );
|
||||
}
|
||||
$offset = 0;
|
||||
$block_size = 512;
|
||||
while( true ) {
|
||||
$args = array(
|
||||
'post_type' => 'shop_order',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => $block_size,
|
||||
'orderby' => get_option( 'wcj_order_numbers_renumerate_tool_orderby', 'date' ),
|
||||
'order' => get_option( 'wcj_order_numbers_renumerate_tool_order', 'ASC' ),
|
||||
'offset' => $offset,
|
||||
'fields' => 'ids',
|
||||
);
|
||||
$loop = new WP_Query( $args );
|
||||
if ( ! $loop->have_posts() ) {
|
||||
break;
|
||||
}
|
||||
foreach ( $loop->posts as $order_id ) {
|
||||
$this->add_order_number_meta( $order_id, true );
|
||||
}
|
||||
$offset += $block_size;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Order_Numbers();
|
||||
@@ -0,0 +1,410 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Order Min/Max Quantities
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.9.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Order_Quantities' ) ) :
|
||||
|
||||
class WCJ_Order_Quantities extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.9.0
|
||||
* @todo maybe rename the module to "Order Quantities" or "Order Product Quantities" or "Product Quantities"?
|
||||
* @todo loop (`woocommerce_loop_add_to_cart_link`)
|
||||
* @todo (maybe) order quantities by user roles
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'order_quantities';
|
||||
$this->short_desc = __( 'Order Min/Max Quantities', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set min/max product quantities in WooCommerce order.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-order-min-max-quantities';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// Min/max quantities
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) || 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
|
||||
add_action( 'woocommerce_checkout_process', array( $this, 'check_order_quantities' ) );
|
||||
add_action( 'woocommerce_before_cart', array( $this, 'check_order_quantities' ) );
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_stop_from_seeing_checkout', 'no' ) ) {
|
||||
add_action( 'wp', array( $this, 'stop_from_seeing_checkout' ), PHP_INT_MAX );
|
||||
}
|
||||
add_filter( 'woocommerce_available_variation', array( $this, 'set_quantity_input_min_max_variation' ), PHP_INT_MAX, 3 );
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_quantity_input_min', array( $this, 'set_quantity_input_min' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_quantity_input_max', array( $this, 'set_quantity_input_max' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_script' ) );
|
||||
}
|
||||
// Quantity step
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_step_section_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_quantity_input_step', array( $this, 'set_quantity_input_step' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
// Meta box
|
||||
$this->is_min_per_product_enabled = ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) &&
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_min_per_item_quantity_per_product', 'no' ) ) );
|
||||
$this->is_max_per_product_enabled = ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) &&
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_max_per_item_quantity_per_product', 'no' ) ) );
|
||||
$this->is_step_per_product_enabled = ( 'yes' === get_option( 'wcj_order_quantities_step_section_enabled', 'no' ) &&
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_step_per_product', 'no' ) ) );
|
||||
if ( $this->is_min_per_product_enabled || $this->is_max_per_product_enabled || $this->is_step_per_product_enabled ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
// Limit cart items (i.e. "Single Item Cart" Mode)
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_single_item_cart_enabled', 'no' ) ) ) {
|
||||
add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'single_item_cart' ), PHP_INT_MAX, 4 );
|
||||
}
|
||||
// For cart
|
||||
add_filter( 'woocommerce_quantity_input_args', array( $this, 'set_quantity_input_args' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set_quantity_input_args.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.7.0
|
||||
*/
|
||||
function set_quantity_input_args( $args, $product ) {
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
|
||||
$args['min_value'] = $this->set_quantity_input_min( $args['min_value'], $product );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
|
||||
$args['max_value'] = $this->set_quantity_input_max( $args['max_value'], $product );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_step_section_enabled', 'no' ) ) {
|
||||
$args['step'] = $this->set_quantity_input_step( $args['step'], $product );
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_quantity_input_step.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.7.0
|
||||
*/
|
||||
function set_quantity_input_step( $qty, $product ) {
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_step_per_product', 'no' ) ) ) {
|
||||
if ( '' != ( $step = get_post_meta( wcj_get_product_id_or_variation_parent_id( $product ), '_' . 'wcj_order_quantities_step', true ) ) && 0 != $step ) {
|
||||
return $step;
|
||||
}
|
||||
}
|
||||
return ( 0 != ( $step = get_option( 'wcj_order_quantities_step', 1 ) ) ? $step : $qty );
|
||||
}
|
||||
|
||||
/**
|
||||
* single_item_cart.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function single_item_cart( $passed, $product_id, $quantity = 0, $variation_id = 0 ) {
|
||||
if ( ! WC()->cart->is_empty() ) {
|
||||
if ( is_array( WC()->cart->cart_contents ) && 1 == count( WC()->cart->cart_contents ) && wcj_is_product_in_cart( ( 0 != $variation_id ? $variation_id : $product_id ) ) ) {
|
||||
return $passed;
|
||||
} else {
|
||||
wc_add_notice( get_option( 'wcj_order_quantities_single_item_cart_message',
|
||||
__( 'Only one item can be added to the cart. Clear the cart or finish the order, before adding another item to the cart.', 'woocommerce-jetpack' ) ), 'error' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $passed;
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_script.
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @since 3.2.2
|
||||
* @todo `force_on_add_to_cart` for simple products
|
||||
* @todo make this optional?
|
||||
*/
|
||||
function enqueue_script() {
|
||||
$_product = wc_get_product();
|
||||
if ( $_product && $_product->is_type( 'variable' ) ) {
|
||||
$quantities_options = array(
|
||||
'reset_to_min' => ( 'reset_to_min' === get_option( 'wcj_order_quantities_variable_variation_change', 'do_nothing' ) ),
|
||||
'reset_to_max' => ( 'reset_to_max' === get_option( 'wcj_order_quantities_variable_variation_change', 'do_nothing' ) ),
|
||||
'force_on_add_to_cart' => ( 'yes' === get_option( 'wcj_order_quantities_variable_force_on_add_to_cart', 'no' ) ),
|
||||
);
|
||||
$product_quantities = array();
|
||||
foreach ( $_product->get_available_variations() as $variation ) {
|
||||
$product_quantities[ $variation['variation_id'] ] = array(
|
||||
'min_qty' => $variation['min_qty'],
|
||||
'max_qty' => $variation['max_qty'],
|
||||
);
|
||||
}
|
||||
wp_enqueue_script( 'wcj-order-quantities', trailingslashit( wcj_plugin_url() ) . 'includes/js/wcj-order-quantities.js', array( 'jquery' ), WCJ()->version, true );
|
||||
wp_localize_script( 'wcj-order-quantities', 'product_quantities', $product_quantities );
|
||||
wp_localize_script( 'wcj-order-quantities', 'quantities_options', $quantities_options );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_product_quantity.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 3.2.2
|
||||
*/
|
||||
function get_product_quantity( $min_or_max, $_product, $default_qty ) {
|
||||
if ( 'no' === get_option( 'wcj_order_quantities_' . $min_or_max . '_section_enabled', 'no' ) ) {
|
||||
return $default_qty;
|
||||
}
|
||||
if (
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity_per_product', 'no' ) ) &&
|
||||
0 != ( $max_or_max_per_item_quantity_per_product = get_post_meta( wcj_get_product_id( $_product ), '_' . 'wcj_order_quantities_' . $min_or_max, true ) )
|
||||
) {
|
||||
return $max_or_max_per_item_quantity_per_product;
|
||||
} elseif ( 0 != ( $max_or_max_per_item_quantity = apply_filters( 'booster_option', 0, get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity', 0 ) ) ) ) {
|
||||
return $max_or_max_per_item_quantity;
|
||||
} else {
|
||||
return $default_qty;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set_quantity_input_min_max_variation.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 3.2.2
|
||||
*/
|
||||
function set_quantity_input_min_max_variation( $args, $_product, $_variation ) {
|
||||
$args['min_qty'] = $this->get_product_quantity( 'min', $_variation, $args['min_qty'] );
|
||||
$args['max_qty'] = $this->get_product_quantity( 'max', $_variation, $args['max_qty'] );
|
||||
$_max = $_variation->get_max_purchase_quantity();
|
||||
if ( -1 != $_max && $args['max_qty'] > $_max ) {
|
||||
$args['max_qty'] = $_max;
|
||||
}
|
||||
if ( $args['min_qty'] < 0 ) {
|
||||
$args['min_qty'] = '';
|
||||
}
|
||||
if ( $args['max_qty'] < 0 ) {
|
||||
$args['max_qty'] = '';
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_quantity_input_min.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 3.2.2
|
||||
*/
|
||||
function set_quantity_input_min( $qty, $_product ) {
|
||||
if ( ! $_product->is_type( 'variable' ) ) {
|
||||
$min = $this->get_product_quantity( 'min', $_product, $qty );
|
||||
$_max = $_product->get_max_purchase_quantity();
|
||||
return ( -1 == $_max || $min < $_max ? $min : $_max );
|
||||
} else {
|
||||
return $qty;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set_quantity_input_max.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 3.2.2
|
||||
*/
|
||||
function set_quantity_input_max( $qty, $_product ) {
|
||||
if ( ! $_product->is_type( 'variable' ) ) {
|
||||
$max = $this->get_product_quantity( 'max', $_product, $qty );
|
||||
$_max = $_product->get_max_purchase_quantity();
|
||||
return ( -1 == $_max || $max < $_max ? $max : $_max );
|
||||
} else {
|
||||
return $qty;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* stop_from_seeing_checkout.
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function stop_from_seeing_checkout() {
|
||||
if ( ! isset( WC()->cart ) ) {
|
||||
return;
|
||||
}
|
||||
if ( ! is_checkout() ) {
|
||||
return;
|
||||
}
|
||||
$cart_item_quantities = WC()->cart->get_cart_item_quantities();
|
||||
if ( empty( $cart_item_quantities ) || ! is_array( $cart_item_quantities ) ) {
|
||||
return;
|
||||
}
|
||||
$cart_total_quantity = array_sum( $cart_item_quantities );
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
|
||||
if ( ! $this->check_quantities( 'max', $cart_item_quantities, $cart_total_quantity, false, true ) ) {
|
||||
wp_safe_redirect( wc_get_cart_url() );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
|
||||
if ( ! $this->check_quantities( 'min', $cart_item_quantities, $cart_total_quantity, false, true ) ) {
|
||||
wp_safe_redirect( wc_get_cart_url() );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* print_message.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function print_message( $message_type, $_is_cart, $required_quantity, $total_quantity, $_product_id = 0 ) {
|
||||
if ( $_is_cart ) {
|
||||
if ( 'no' === get_option( 'wcj_order_quantities_cart_notice_enabled', 'no' ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch ( $message_type ) {
|
||||
case 'max_cart_total_quantity':
|
||||
$replaced_values = array(
|
||||
'%max_cart_total_quantity%' => $required_quantity,
|
||||
'%cart_total_quantity%' => $total_quantity,
|
||||
);
|
||||
$message_template = get_option( 'wcj_order_quantities_max_cart_total_message',
|
||||
__( 'Maximum allowed order quantity is %max_cart_total_quantity%. Your current order quantity is %cart_total_quantity%.', 'woocommerce-jetpack' ) );
|
||||
break;
|
||||
case 'min_cart_total_quantity':
|
||||
$replaced_values = array(
|
||||
'%min_cart_total_quantity%' => $required_quantity,
|
||||
'%cart_total_quantity%' => $total_quantity,
|
||||
);
|
||||
$message_template = get_option( 'wcj_order_quantities_min_cart_total_message',
|
||||
__( 'Minimum allowed order quantity is %min_cart_total_quantity%. Your current order quantity is %cart_total_quantity%.', 'woocommerce-jetpack' ) );
|
||||
break;
|
||||
case 'max_per_item_quantity':
|
||||
$_product = wc_get_product( $_product_id );
|
||||
$replaced_values = array(
|
||||
'%max_per_item_quantity%' => $required_quantity,
|
||||
'%item_quantity%' => $total_quantity,
|
||||
'%product_title%' => $_product->get_title(),
|
||||
);
|
||||
$message_template = get_option( 'wcj_order_quantities_max_per_item_message',
|
||||
__( 'Maximum allowed quantity for %product_title% is %max_per_item_quantity%. Your current item quantity is %item_quantity%.', 'woocommerce-jetpack' ) );
|
||||
break;
|
||||
case 'min_per_item_quantity':
|
||||
$_product = wc_get_product( $_product_id );
|
||||
$replaced_values = array(
|
||||
'%min_per_item_quantity%' => $required_quantity,
|
||||
'%item_quantity%' => $total_quantity,
|
||||
'%product_title%' => $_product->get_title(),
|
||||
);
|
||||
$message_template = get_option( 'wcj_order_quantities_min_per_item_message',
|
||||
__( 'Minimum allowed quantity for %product_title% is %min_per_item_quantity%. Your current item quantity is %item_quantity%.', 'woocommerce-jetpack' ) );
|
||||
break;
|
||||
}
|
||||
$_notice = str_replace( array_keys( $replaced_values ), array_values( $replaced_values ), $message_template );
|
||||
if ( $_is_cart ) {
|
||||
wc_print_notice( $_notice, 'notice' );
|
||||
} else {
|
||||
wc_add_notice( $_notice, 'error' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check_quantities.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function check_quantities( $min_or_max, $cart_item_quantities, $cart_total_quantity, $_is_cart, $_return ) {
|
||||
if ( 0 != ( $min_or_max_cart_total_quantity = get_option( 'wcj_order_quantities_' . $min_or_max . '_cart_total_quantity', 0 ) ) ) {
|
||||
if (
|
||||
( 'max' === $min_or_max && $cart_total_quantity > $min_or_max_cart_total_quantity ) ||
|
||||
( 'min' === $min_or_max && $cart_total_quantity < $min_or_max_cart_total_quantity )
|
||||
) {
|
||||
if ( $_return ) {
|
||||
return false;
|
||||
} else {
|
||||
$this->print_message( $min_or_max . '_cart_total_quantity', $_is_cart, $min_or_max_cart_total_quantity, $cart_total_quantity );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity_per_product', 'no' ) ) ) {
|
||||
foreach ( $cart_item_quantities as $_product_id => $cart_item_quantity ) {
|
||||
if ( 0 != ( $max_or_max_per_item_quantity = get_post_meta( $_product_id, '_' . 'wcj_order_quantities_' . $min_or_max, true ) ) ) {
|
||||
if (
|
||||
( 'max' === $min_or_max && $cart_item_quantity > $max_or_max_per_item_quantity ) ||
|
||||
( 'min' === $min_or_max && $cart_item_quantity < $max_or_max_per_item_quantity )
|
||||
) {
|
||||
if ( $_return ) {
|
||||
return false;
|
||||
} else {
|
||||
$this->print_message( $min_or_max . '_per_item_quantity', $_is_cart, $max_or_max_per_item_quantity, $cart_item_quantity, $_product_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( 0 != ( $max_or_max_per_item_quantity = apply_filters( 'booster_option', 0, get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity', 0 ) ) ) ) {
|
||||
foreach ( $cart_item_quantities as $_product_id => $cart_item_quantity ) {
|
||||
if (
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_' . $min_or_max . '_per_item_quantity_per_product', 'no' ) ) &&
|
||||
0 != get_post_meta( $_product_id, '_' . 'wcj_order_quantities_' . $min_or_max, true )
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
( 'max' === $min_or_max && $cart_item_quantity > $max_or_max_per_item_quantity ) ||
|
||||
( 'min' === $min_or_max && $cart_item_quantity < $max_or_max_per_item_quantity )
|
||||
) {
|
||||
if ( $_return ) {
|
||||
return false;
|
||||
} else {
|
||||
$this->print_message( $min_or_max . '_per_item_quantity', $_is_cart, $max_or_max_per_item_quantity, $cart_item_quantity, $_product_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $_return ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check_order_quantities.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function check_order_quantities() {
|
||||
if ( ! isset( WC()->cart ) ) {
|
||||
return;
|
||||
}
|
||||
$cart_item_quantities = WC()->cart->get_cart_item_quantities();
|
||||
if ( empty( $cart_item_quantities ) || ! is_array( $cart_item_quantities ) ) {
|
||||
return;
|
||||
}
|
||||
$cart_total_quantity = array_sum( $cart_item_quantities );
|
||||
$_is_cart = is_cart();
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_max_section_enabled', 'no' ) ) {
|
||||
$this->check_quantities( 'max', $cart_item_quantities, $cart_total_quantity, $_is_cart, false );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_order_quantities_min_section_enabled', 'no' ) ) {
|
||||
$this->check_quantities( 'min', $cart_item_quantities, $cart_total_quantity, $_is_cart, false );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Order_Quantities();
|
||||
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Orders
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Orders' ) ) :
|
||||
|
||||
class WCJ_Orders extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @todo Bulk Regenerate Download Permissions - copy "cron" to plugin
|
||||
* @todo Bulk Regenerate Download Permissions - maybe move "bulk actions" to free
|
||||
* @todo Bulk Regenerate Download Permissions - maybe as new module
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'orders';
|
||||
$this->short_desc = __( 'Orders', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Orders auto-complete; admin order currency; admin order navigation; bulk regenerate download permissions for orders.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-orders';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
// Order auto complete
|
||||
if ( 'yes' === get_option( 'wcj_order_auto_complete_enabled', 'no' ) ) {
|
||||
add_action( 'woocommerce_thankyou', array( $this, 'auto_complete_order' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_payment_complete', array( $this, 'auto_complete_order' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Order currency
|
||||
if ( 'yes' === get_option( 'wcj_order_admin_currency', 'no' ) ) {
|
||||
$this->meta_box_screen = 'shop_order';
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_shop_order', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
if ( 'filter' === get_option( 'wcj_order_admin_currency_method', 'filter' ) ) {
|
||||
$woocommerce_get_order_currency_filter = ( WCJ_IS_WC_VERSION_BELOW_3 ? 'woocommerce_get_order_currency' : 'woocommerce_order_get_currency' );
|
||||
add_filter( $woocommerce_get_order_currency_filter, array( $this, 'change_order_currency' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
// Bulk Regenerate Download Permissions
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_bulk_regenerate_download_permissions_enabled', 'no' ) ) ) {
|
||||
// Actions
|
||||
if ( 'yes' === get_option( 'wcj_order_bulk_regenerate_download_permissions_actions', 'no' ) ) {
|
||||
add_filter( 'bulk_actions-edit-shop_order', array( $this, 'register_bulk_actions_regenerate_download_permissions' ), PHP_INT_MAX );
|
||||
add_filter( 'handle_bulk_actions-edit-shop_order', array( $this, 'handle_bulk_actions_regenerate_download_permissions' ), 10, 3 );
|
||||
}
|
||||
// All orders
|
||||
add_action( 'woojetpack_after_settings_save', array( $this, 'maybe_bulk_regenerate_download_permissions_all_orders' ) );
|
||||
// Admin notices
|
||||
add_filter( 'admin_notices', array( $this, 'admin_notice_regenerate_download_permissions' ) );
|
||||
// All orders - Cron
|
||||
if ( 'disabled' != apply_filters( 'booster_option', 'disabled', get_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders_cron', 'disabled' ) ) ) {
|
||||
add_action( 'init', array( $this, 'schedule_bulk_regenerate_download_permissions_all_orders_cron' ) );
|
||||
add_action( 'admin_init', array( $this, 'schedule_bulk_regenerate_download_permissions_all_orders_cron' ) );
|
||||
add_filter( 'cron_schedules', 'wcj_crons_add_custom_intervals' );
|
||||
add_action( 'wcj_bulk_regenerate_download_permissions_all_orders_cron', array( $this, 'bulk_regenerate_download_permissions_all_orders' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Country by IP
|
||||
if ( 'yes' === get_option( 'wcj_orders_country_by_ip_enabled', 'no' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_country_by_ip_meta_box' ) );
|
||||
}
|
||||
|
||||
// Orders navigation
|
||||
if ( 'yes' === get_option( 'wcj_orders_navigation_enabled', 'no' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_orders_navigation_meta_box' ) );
|
||||
add_action( 'admin_init', array( $this, 'handle_orders_navigation' ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle_orders_navigation.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
*/
|
||||
function handle_orders_navigation() {
|
||||
if ( isset( $_GET['wcj_orders_navigation'] ) ) {
|
||||
$url = ( ! isset( $_GET['post'] ) || false === ( $adjacent_order_id = wcj_get_adjacent_order_id( $_GET['post'], $_GET['wcj_orders_navigation'] ) ) ?
|
||||
remove_query_arg( 'wcj_orders_navigation' ) :
|
||||
admin_url( 'post.php?post=' . $adjacent_order_id . '&action=edit' ) );
|
||||
wp_safe_redirect( $url );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_orders_navigation_meta_box.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
*/
|
||||
function add_orders_navigation_meta_box() {
|
||||
add_meta_box(
|
||||
'wc-jetpack-' . $this->id . '-navigation',
|
||||
__( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Order Navigation', 'woocommerce-jetpack' ),
|
||||
array( $this, 'create_orders_navigation_meta_box' ),
|
||||
'shop_order',
|
||||
'side',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_orders_navigation_meta_box.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
* @todo this will output the link, even if there no prev/next orders available
|
||||
*/
|
||||
function create_orders_navigation_meta_box() {
|
||||
echo '<a href="' . add_query_arg( 'wcj_orders_navigation', 'prev' ) . '">' . '<< ' . __( 'Previous order', 'woocommerce-jetpack' ) . '</a>' .
|
||||
'<a href="' . add_query_arg( 'wcj_orders_navigation', 'next' ) . '" style="float:right;">' . __( 'Next order', 'woocommerce-jetpack' ) . ' >>' . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* add_country_by_ip_meta_box.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function add_country_by_ip_meta_box() {
|
||||
add_meta_box(
|
||||
'wc-jetpack-' . $this->id . '-country-by-ip',
|
||||
__( 'Booster', 'woocommerce-jetpack' ) . ': ' . __( 'Country by IP', 'woocommerce-jetpack' ),
|
||||
array( $this, 'create_country_by_ip_meta_box' ),
|
||||
'shop_order',
|
||||
'side',
|
||||
'low'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_country_by_ip_meta_box.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function create_country_by_ip_meta_box() {
|
||||
if (
|
||||
class_exists( 'WC_Geolocation' ) &&
|
||||
( $order = wc_get_order() ) &&
|
||||
( $customer_ip = $order->get_customer_ip_address() ) &&
|
||||
( $location = WC_Geolocation::geolocate_ip( $customer_ip ) ) &&
|
||||
isset( $location['country'] ) && '' != $location['country']
|
||||
) {
|
||||
echo wcj_get_country_flag_by_code( $location['country'] ) . ' ' .
|
||||
wcj_get_country_name_by_code( $location['country'] ) .
|
||||
' (' . $location['country'] . ')' .
|
||||
' [' . $customer_ip . ']';
|
||||
} else {
|
||||
echo '<em>' . __( 'No data.', 'woocommerce-jetpack' ) . '</em>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* schedule_bulk_regenerate_download_permissions_all_orders_cron.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function schedule_bulk_regenerate_download_permissions_all_orders_cron() {
|
||||
wcj_crons_schedule_the_events(
|
||||
'wcj_bulk_regenerate_download_permissions_all_orders_cron',
|
||||
apply_filters( 'booster_option', 'disabled', get_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders_cron', 'disabled' ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* handle_bulk_actions_regenerate_download_permissions.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 3.2.0
|
||||
* @see https://make.wordpress.org/core/2016/10/04/custom-bulk-actions/
|
||||
* @todo (maybe) "bulk actions" for for WP < 4.7
|
||||
*/
|
||||
function handle_bulk_actions_regenerate_download_permissions( $redirect_to, $doaction, $post_ids ) {
|
||||
if ( $doaction !== 'wcj_regenerate_download_permissions' ) {
|
||||
return $redirect_to;
|
||||
}
|
||||
$data_store = WC_Data_Store::load( 'customer-download' );
|
||||
foreach ( $post_ids as $post_id ) {
|
||||
$data_store->delete_by_order_id( $post_id );
|
||||
wc_downloadable_product_permissions( $post_id, true );
|
||||
}
|
||||
$redirect_to = add_query_arg( 'wcj_bulk_regenerated_download_permissions', count( $post_ids ), $redirect_to );
|
||||
return $redirect_to;
|
||||
}
|
||||
|
||||
/**
|
||||
* register_bulk_actions_regenerate_download_permissions.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 3.2.0
|
||||
*/
|
||||
function register_bulk_actions_regenerate_download_permissions( $bulk_actions ) {
|
||||
$bulk_actions['wcj_regenerate_download_permissions'] = __( 'Regenerate download permissions', 'woocommerce-jetpack' );
|
||||
return $bulk_actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* admin_notice_regenerate_download_permissions.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 3.2.0
|
||||
*/
|
||||
function admin_notice_regenerate_download_permissions() {
|
||||
if ( ! empty( $_REQUEST['wcj_bulk_regenerated_download_permissions'] ) ) {
|
||||
$orders_count = intval( $_REQUEST['wcj_bulk_regenerated_download_permissions'] );
|
||||
$message = sprintf(
|
||||
_n( 'Download permissions regenerated for %s order.', 'Download permissions regenerated for %s orders.', $orders_count, 'woocommerce-jetpack' ),
|
||||
'<strong>' . $orders_count . '</strong>'
|
||||
);
|
||||
echo '<div class="notice notice-success is-dismissible"><p>' . $message . '</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* bulk_regenerate_download_permissions_all_orders.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 3.2.0
|
||||
*/
|
||||
function bulk_regenerate_download_permissions_all_orders() {
|
||||
$data_store = WC_Data_Store::load( 'customer-download' );
|
||||
$block_size = 512;
|
||||
$offset = 0;
|
||||
$total_orders = 0;
|
||||
while( true ) {
|
||||
$args = array(
|
||||
'post_type' => 'shop_order',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => $block_size,
|
||||
'offset' => $offset,
|
||||
'orderby' => 'ID',
|
||||
'order' => 'DESC',
|
||||
'fields' => 'ids',
|
||||
);
|
||||
$loop = new WP_Query( $args );
|
||||
if ( ! $loop->have_posts() ) {
|
||||
break;
|
||||
}
|
||||
foreach ( $loop->posts as $post_id ) {
|
||||
$data_store->delete_by_order_id( $post_id );
|
||||
wc_downloadable_product_permissions( $post_id, true );
|
||||
$total_orders++;
|
||||
}
|
||||
$offset += $block_size;
|
||||
}
|
||||
return $total_orders;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_bulk_regenerate_download_permissions_all_orders.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 3.2.0
|
||||
*/
|
||||
function maybe_bulk_regenerate_download_permissions_all_orders() {
|
||||
if ( 'yes' === get_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders', 'no' ) ) {
|
||||
update_option( 'wcj_order_bulk_regenerate_download_permissions_all_orders', 'no' );
|
||||
$total_orders = $this->bulk_regenerate_download_permissions_all_orders();
|
||||
wp_safe_redirect( add_query_arg( 'wcj_bulk_regenerated_download_permissions', $total_orders ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_order_currency.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.6
|
||||
* @todo (maybe) move meta box to `side`
|
||||
*/
|
||||
function change_order_currency( $order_currency, $_order ) {
|
||||
return ( '' != ( $wcj_order_currency = get_post_meta( wcj_get_order_id( $_order ), '_' . 'wcj_order_currency', true ) ) ) ? $wcj_order_currency : $order_currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto Complete all WooCommerce orders.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @todo (maybe) at first check if status is not `completed` already (however `WC_Order::set_status()` checks that anyway)
|
||||
*/
|
||||
function auto_complete_order( $order_id ) {
|
||||
if ( ! $order_id ) {
|
||||
return;
|
||||
}
|
||||
$order = wc_get_order( $order_id );
|
||||
$payment_methods = apply_filters( 'booster_option', '', get_option( 'wcj_order_auto_complete_payment_methods', array() ) );
|
||||
if ( ! empty( $payment_methods ) && ! in_array( $order->get_payment_method(), $payment_methods ) ) {
|
||||
return;
|
||||
}
|
||||
$order->update_status( 'completed' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Orders();
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Payment Gateways by Country
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.4.1
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Payment_Gateways_By_Country' ) ) :
|
||||
|
||||
class WCJ_Payment_Gateways_By_Country extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'payment_gateways_by_country';
|
||||
$this->short_desc = __( 'Gateways by Country, State or Postcode', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set countries, states or postcodes to include/exclude for payment gateways to show up.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-payment-gateways-by-country-or-state';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_location.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.4.0
|
||||
* @todo on `WCJ_IS_WC_VERSION_BELOW_3` recheck if `get_shipping_country()` and `get_shipping_state()` work correctly
|
||||
*/
|
||||
function get_location( $type ) {
|
||||
switch ( $type ) {
|
||||
case 'country':
|
||||
$country_type = get_option( 'wcj_gateways_by_location_country_type', 'billing' );
|
||||
return ( 'by_ip' === $country_type ?
|
||||
wcj_get_country_by_ip() :
|
||||
( isset( WC()->customer ) ? ( 'billing' === $country_type ? wcj_customer_get_country() : WC()->customer->get_shipping_country() ) : '' ) );
|
||||
case 'state':
|
||||
return ( isset( WC()->customer ) ?
|
||||
( 'billing' === get_option( 'wcj_gateways_by_location_state_type', 'billing' ) ? wcj_customer_get_country_state() : WC()->customer->get_shipping_state() ) :
|
||||
'' );
|
||||
case 'postcode':
|
||||
$postcode = '';
|
||||
if ( isset( $_REQUEST['postcode'] ) && 'billing' === get_option( 'wcj_gateways_by_location_postcodes_type', 'billing' ) ) {
|
||||
$postcode = $_REQUEST['postcode'];
|
||||
} elseif ( isset( $_REQUEST['s_postcode'] ) && 'shipping' === get_option( 'wcj_gateways_by_location_postcodes_type', 'billing' ) ) {
|
||||
$postcode = $_REQUEST['s_postcode'];
|
||||
}
|
||||
if ( '' == $postcode ) {
|
||||
$postcode = WC()->countries->get_base_postcode();
|
||||
}
|
||||
return strtoupper( $postcode );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* range_match.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
*/
|
||||
function range_match( $postcode_range, $postcode_to_check ) {
|
||||
$postcode_range = explode( '...', $postcode_range );
|
||||
return ( 2 === count( $postcode_range ) && $postcode_to_check >= $postcode_range[0] && $postcode_to_check <= $postcode_range[1] );
|
||||
}
|
||||
|
||||
/**
|
||||
* check_postcode.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
*/
|
||||
function check_postcode( $postcode_to_check, $postcodes ) {
|
||||
foreach ( $postcodes as $postcode ) {
|
||||
if (
|
||||
( false !== strpos( $postcode, '*' ) && fnmatch( $postcode, $postcode_to_check ) ) ||
|
||||
( false !== strpos( $postcode, '...' ) && $this->range_match( $postcode, $postcode_to_check ) ) ||
|
||||
( $postcode === $postcode_to_check )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* available_payment_gateways.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @todo (maybe) rename module to "Payment Gateways by (Customer's) Location"
|
||||
* @todo (maybe) check naming, should be `wcj_gateways_by_location_` (however it's too long...)
|
||||
* @todo (maybe) code refactoring
|
||||
* @todo (maybe) add more locations options (e.g. "... by city")
|
||||
* @todo (maybe) add option to detect customer's country and state by current `$_REQUEST` (as it is now done with postcodes)
|
||||
*/
|
||||
function available_payment_gateways( $_available_gateways ) {
|
||||
$customer_country = $this->get_location( 'country' );
|
||||
$customer_state = $this->get_location( 'state' );
|
||||
$postcode = $this->get_location( 'postcode' );
|
||||
foreach ( $_available_gateways as $key => $gateway ) {
|
||||
if ( '' != $customer_country ) {
|
||||
$include_countries = wcj_maybe_add_european_union_countries( get_option( 'wcj_gateways_countries_include_' . $key, '' ) );
|
||||
if ( ! empty( $include_countries ) && ! in_array( $customer_country, $include_countries ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
$exclude_countries = get_option( 'wcj_gateways_countries_exclude_' . $key, '' );
|
||||
if ( ! empty( $exclude_countries ) && in_array( $customer_country, $exclude_countries ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( '' != $customer_state ) {
|
||||
$include_states = get_option( 'wcj_gateways_states_include_' . $key, '' );
|
||||
if ( ! empty( $include_states ) && ! in_array( $customer_state, $include_states ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
$exclude_states = get_option( 'wcj_gateways_states_exclude_' . $key, '' );
|
||||
if ( ! empty( $exclude_states ) && in_array( $customer_state, $exclude_states ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( '' != $postcode ) {
|
||||
$include_postcodes = get_option( 'wcj_gateways_postcodes_include_' . $key, '' );
|
||||
if ( ! empty( $include_postcodes ) ) {
|
||||
$include_postcodes = array_filter( array_map( 'strtoupper', array_map( 'wc_clean', explode( "\n", $include_postcodes ) ) ) );
|
||||
if ( ! $this->check_postcode( $postcode, $include_postcodes ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$exclude_postcodes = get_option( 'wcj_gateways_postcodes_exclude_' . $key, '' );
|
||||
if ( ! empty( $exclude_postcodes ) ) {
|
||||
$exclude_postcodes = array_filter( array_map( 'strtoupper', array_map( 'wc_clean', explode( "\n", $exclude_postcodes ) ) ) );
|
||||
if ( $this->check_postcode( $postcode, $exclude_postcodes ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $_available_gateways;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Payment_Gateways_By_Country();
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Gateways by Currency
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 3.0.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Payment_Gateways_By_Currency' ) ) :
|
||||
|
||||
class WCJ_Payment_Gateways_By_Currency extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'payment_gateways_by_currency';
|
||||
$this->short_desc = __( 'Gateways by Currency', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set allowed currencies for payment gateways to show up.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-payment-gateways-by-currency';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* available_payment_gateways.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function available_payment_gateways( $_available_gateways ) {
|
||||
$current_currency = get_woocommerce_currency();
|
||||
foreach ( $_available_gateways as $key => $gateway ) {
|
||||
$allowed_currencies = get_option( 'wcj_gateways_by_currency_allowed_' . $key, '' );
|
||||
if ( ! empty( $allowed_currencies ) && ! in_array( $current_currency, $allowed_currencies ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
$denied_currencies = get_option( 'wcj_gateways_by_currency_denied_' . $key, '' );
|
||||
if ( ! empty( $denied_currencies ) && in_array( $current_currency, $denied_currencies ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return $_available_gateways;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Payment_Gateways_By_Currency();
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Payment Gateways by Shipping
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.7.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Payment_Gateways_By_Shipping' ) ) :
|
||||
|
||||
class WCJ_Payment_Gateways_By_Shipping extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.7.0
|
||||
* @todo re-check in which more modules `use_shipping_instance` can be used
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'payment_gateways_by_shipping';
|
||||
$this->short_desc = __( 'Gateways by Shipping', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set "enable for shipping methods" for payment gateways.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-payment-gateways-by-shipping';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
$this->use_shipping_instance = ( 'yes' === get_option( 'wcj_payment_gateways_by_shipping_use_shipping_instance', 'no' ) );
|
||||
add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check_if_enabled_for_methods.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.7.0
|
||||
* @see `is_available()` function in WooCommerce `WC_Gateway_COD` class
|
||||
* @todo (maybe) virtual orders (`enable_for_virtual`)
|
||||
*/
|
||||
function check_if_enabled_for_methods( $gateway_key, $enable_for_methods ) {
|
||||
|
||||
$order = null;
|
||||
$needs_shipping = false;
|
||||
|
||||
// Test if shipping is needed first
|
||||
if ( WC()->cart && WC()->cart->needs_shipping() ) {
|
||||
$needs_shipping = true;
|
||||
} elseif ( is_page( wc_get_page_id( 'checkout' ) ) && 0 < get_query_var( 'order-pay' ) ) {
|
||||
$order_id = absint( get_query_var( 'order-pay' ) );
|
||||
$order = wc_get_order( $order_id );
|
||||
|
||||
// Test if order needs shipping.
|
||||
if ( 0 < sizeof( $order->get_items() ) ) {
|
||||
foreach ( $order->get_items() as $item ) {
|
||||
$_product = $order->get_product_from_item( $item );
|
||||
if ( $_product && $_product->needs_shipping() ) {
|
||||
$needs_shipping = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$needs_shipping = apply_filters( 'woocommerce_cart_needs_shipping', $needs_shipping );
|
||||
|
||||
// Virtual order, with virtual disabled
|
||||
/*
|
||||
if ( ! $this->enable_for_virtual && ! $needs_shipping ) {
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
// Check methods
|
||||
if ( ! empty( $enable_for_methods ) && $needs_shipping ) {
|
||||
|
||||
// Only apply if all packages are being shipped via chosen methods, or order is virtual
|
||||
$chosen_shipping_methods_session = WC()->session->get( 'chosen_shipping_methods' );
|
||||
|
||||
if ( isset( $chosen_shipping_methods_session ) ) {
|
||||
$chosen_shipping_methods = array_unique( $chosen_shipping_methods_session );
|
||||
} else {
|
||||
$chosen_shipping_methods = array();
|
||||
}
|
||||
|
||||
$check_method = false;
|
||||
|
||||
if ( is_object( $order ) ) {
|
||||
if ( $order->shipping_method ) {
|
||||
$check_method = $order->shipping_method;
|
||||
}
|
||||
|
||||
} elseif ( empty( $chosen_shipping_methods ) || sizeof( $chosen_shipping_methods ) > 1 ) {
|
||||
$check_method = false;
|
||||
} elseif ( sizeof( $chosen_shipping_methods ) == 1 ) {
|
||||
$check_method = $chosen_shipping_methods[0];
|
||||
}
|
||||
|
||||
if ( ! $check_method ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$found = false;
|
||||
|
||||
// Shipping method instance
|
||||
if ( $this->use_shipping_instance ) {
|
||||
$check_method = explode( ':', $check_method, 2 );
|
||||
if ( ! isset( $check_method[1] ) || ! is_numeric( $check_method[1] ) ) {
|
||||
return false;
|
||||
} else {
|
||||
$check_method = $check_method[1];
|
||||
}
|
||||
}
|
||||
|
||||
// Final check
|
||||
foreach ( $enable_for_methods as $method_id ) {
|
||||
if ( $this->use_shipping_instance ) {
|
||||
if ( $check_method == $method_id ) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ( strpos( $check_method, $method_id ) === 0 ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $found ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* available_payment_gateways.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function available_payment_gateways( $_available_gateways ) {
|
||||
foreach ( $_available_gateways as $key => $gateway ) {
|
||||
$enable_for_methods = ( $this->use_shipping_instance ?
|
||||
get_option( 'wcj_gateways_by_shipping_enable_instance_' . $key, '' ) :
|
||||
get_option( 'wcj_gateways_by_shipping_enable_' . $key, '' ) );
|
||||
if ( ! empty( $enable_for_methods ) && ! $this->check_if_enabled_for_methods( $key, $enable_for_methods ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return $_available_gateways;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Payment_Gateways_By_Shipping();
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Gateways by User Role
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.5.3
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Payment_Gateways_By_User_Role' ) ) :
|
||||
|
||||
class WCJ_Payment_Gateways_By_User_Role extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.2
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'payment_gateways_by_user_role';
|
||||
$this->short_desc = __( 'Gateways by User Role', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set user roles to include/exclude for payment gateways to show up.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-payment-gateways-by-user-role';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX - 100, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* available_payment_gateways.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function available_payment_gateways( $_available_gateways ) {
|
||||
$customer_role = wcj_get_current_user_first_role();
|
||||
foreach ( $_available_gateways as $key => $gateway ) {
|
||||
$include_roles = get_option( 'wcj_gateways_user_roles_include_' . $key, '' );
|
||||
if ( ! empty( $include_roles ) && ! in_array( $customer_role, $include_roles ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
$exclude_roles = get_option( 'wcj_gateways_user_roles_exclude_' . $key, '' );
|
||||
if ( ! empty( $exclude_roles ) && in_array( $customer_role, $exclude_roles ) ) {
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return $_available_gateways;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Payment_Gateways_By_User_Role();
|
||||
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Gateways Currency
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 2.3.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Payment_Gateways_Currency' ) ) :
|
||||
|
||||
class WCJ_Payment_Gateways_Currency extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.0.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'payment_gateways_currency';
|
||||
$this->short_desc = __( 'Gateways Currency Converter', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Currency converter for payment gateways.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-payment-gateways-currency-converter';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// add_action( 'init', array( $this, 'add_hooks' ) );
|
||||
$this->add_hooks();
|
||||
if ( is_admin() ) {
|
||||
include_once( 'reports/class-wcj-currency-reports.php' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_hooks.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.3.2
|
||||
*/
|
||||
function add_hooks() {
|
||||
add_filter( 'woocommerce_currency_symbol', array( $this, 'change_currency_symbol' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_currency', array( $this, 'change_currency_code' ), PHP_INT_MAX, 1 );
|
||||
|
||||
add_filter( 'woocommerce_paypal_supported_currencies', array( $this, 'extend_paypal_supported_currencies' ), PHP_INT_MAX, 1 );
|
||||
|
||||
add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'change_price_by_gateway' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_product_variation_get_price', array( $this, 'change_price_by_gateway' ), PHP_INT_MAX, 2 );
|
||||
|
||||
add_filter( 'woocommerce_package_rates', array( $this, 'change_shipping_price_by_gateway' ), PHP_INT_MAX, 2 );
|
||||
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_checkout_script' ) );
|
||||
add_action( 'init', array( $this, 'register_script' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_shipping_price_by_gateway.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function change_shipping_price_by_gateway( $package_rates, $package ) {
|
||||
if ( $this->is_cart_or_checkout() ) {
|
||||
global $woocommerce;
|
||||
$current_gateway = $woocommerce->session->chosen_payment_method;
|
||||
if ( '' != $current_gateway ) {
|
||||
$gateway_currency_exchange_rate = get_option( 'wcj_gateways_currency_exchange_rate_' . $current_gateway );
|
||||
return wcj_change_price_shipping_package_rates( $package_rates, $gateway_currency_exchange_rate );
|
||||
}
|
||||
}
|
||||
return $package_rates;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_cart_or_checkout.
|
||||
*
|
||||
* @version 2.3.5
|
||||
*/
|
||||
function is_cart_or_checkout() {
|
||||
// if ( wcj_is_frontend() ) {
|
||||
if ( ! is_admin() ) {
|
||||
if ( is_cart() || is_checkout() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_by_gateway.
|
||||
*/
|
||||
function change_price_by_gateway( $price, $product ) {
|
||||
if ( $this->is_cart_or_checkout() ) {
|
||||
global $woocommerce;
|
||||
$current_gateway = $woocommerce->session->chosen_payment_method;
|
||||
if ( '' != $current_gateway ) {
|
||||
$gateway_currency_exchange_rate = get_option( 'wcj_gateways_currency_exchange_rate_' . $current_gateway );
|
||||
$price = $price * $gateway_currency_exchange_rate;
|
||||
}
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* extend_paypal_supported_currencies.
|
||||
*
|
||||
* @version 2.4.0
|
||||
*/
|
||||
function extend_paypal_supported_currencies( $supported_currencies ) {
|
||||
if ( $this->is_cart_or_checkout() ) {
|
||||
global $woocommerce;
|
||||
$current_gateway = $woocommerce->session->chosen_payment_method;
|
||||
if ( '' != $current_gateway ) {
|
||||
$gateway_currency = get_option( 'wcj_gateways_currency_' . $current_gateway );
|
||||
if ( 'no_changes' != $gateway_currency ) {
|
||||
$supported_currencies[] = $gateway_currency;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $supported_currencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_currency_symbol.
|
||||
*
|
||||
* @version 2.4.0
|
||||
*/
|
||||
function change_currency_symbol( $currency_symbol, $currency ) {
|
||||
if ( $this->is_cart_or_checkout() ) {
|
||||
global $woocommerce;
|
||||
$current_gateway = $woocommerce->session->chosen_payment_method;
|
||||
if ( '' != $current_gateway ) {
|
||||
$gateway_currency = get_option( 'wcj_gateways_currency_' . $current_gateway );
|
||||
if ( 'no_changes' != $gateway_currency ) {
|
||||
return wcj_get_currency_symbol( $gateway_currency );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $currency_symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_currency_code.
|
||||
*
|
||||
* @version 2.4.0
|
||||
*/
|
||||
function change_currency_code( $currency ) {
|
||||
if ( $this->is_cart_or_checkout() ) {
|
||||
global $woocommerce;
|
||||
$current_gateway = $woocommerce->session->chosen_payment_method;
|
||||
/*
|
||||
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
|
||||
if ( ! array_key_exists( $current_gateway, $available_gateways ) ) {
|
||||
$current_gateway = get_option( 'woocommerce_default_gateway', '' );
|
||||
if ( '' == $current_gateway ) {
|
||||
$current_gateway = current( $available_gateways );
|
||||
$current_gateway = isset( $current_gateway->id ) ? $current_gateway->id : '';
|
||||
}
|
||||
}
|
||||
*/
|
||||
if ( '' != $current_gateway ) {
|
||||
$gateway_currency = get_option( 'wcj_gateways_currency_' . $current_gateway );
|
||||
if ( 'no_changes' != $gateway_currency ) {
|
||||
return $gateway_currency;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* register_script.
|
||||
*
|
||||
* @version 2.9.0
|
||||
*/
|
||||
function register_script() {
|
||||
wp_register_script( 'wcj-payment-gateways-checkout', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'js/wcj-checkout.js', array( 'jquery' ), WCJ()->version, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_checkout_script.
|
||||
*/
|
||||
function enqueue_checkout_script() {
|
||||
if( ! is_checkout() ) {
|
||||
return;
|
||||
}
|
||||
wp_enqueue_script( 'wcj-payment-gateways-checkout' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Payment_Gateways_Currency();
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Gateways Fees and Discounts
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.2.2
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Payment_Gateways_Fees' ) ) :
|
||||
|
||||
class WCJ_Payment_Gateways_Fees extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @todo (maybe) move all settings to arrays
|
||||
* @todo (maybe) add settings subsections for each gateway
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'payment_gateways_fees';
|
||||
$this->short_desc = __( 'Gateways Fees and Discounts', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Enable extra fees or discounts for payment gateways.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-payment-gateways-fees-and-discounts';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'woocommerce_cart_calculate_fees', array( $this, 'gateways_fees' ) );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_checkout_script' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_checkout_script.
|
||||
*
|
||||
* @version 2.9.0
|
||||
*/
|
||||
function enqueue_checkout_script() {
|
||||
if( ! is_checkout() ) {
|
||||
return;
|
||||
}
|
||||
wp_enqueue_script( 'wcj-payment-gateways-checkout', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'js/wcj-checkout.js', array( 'jquery' ), WCJ()->version, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* get_current_gateway.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function get_current_gateway() {
|
||||
if ( isset( $_GET['wc-api'] ) && 'WC_Gateway_PayPal_Express_AngellEYE' === $_GET['wc-api'] ) {
|
||||
return 'paypal_express'; // PayPal for WooCommerce (By Angell EYE)
|
||||
} elseif (
|
||||
( isset( $_GET['wc-ajax'] ) && 'wc_ppec_generate_cart' === $_GET['wc-ajax'] ) ||
|
||||
( isset( $_GET['startcheckout'] ) && 'true' === $_GET['startcheckout'] )
|
||||
) {
|
||||
return 'ppec_paypal'; // WooCommerce PayPal Express Checkout Payment Gateway (By WooCommerce)
|
||||
} else {
|
||||
return WC()->session->chosen_payment_method;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check_cart_products.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.7.0
|
||||
* @todo add WPML support
|
||||
* @todo add product variations
|
||||
* @todo add product cats and tags
|
||||
*/
|
||||
function check_cart_products( $gateway ) {
|
||||
$require_products = apply_filters( 'booster_option', array(), get_option( 'wcj_gateways_fees_include_products', array() ) );
|
||||
if ( ! empty( $require_products[ $gateway ] ) ) {
|
||||
$passed = false;
|
||||
foreach ( WC()->cart->get_cart() as $item ) {
|
||||
if ( in_array( $item['product_id'], $require_products[ $gateway ] ) ) {
|
||||
$passed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! $passed ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$exclude_products = apply_filters( 'booster_option', array(), get_option( 'wcj_gateways_fees_exclude_products', array() ) );
|
||||
if ( ! empty( $exclude_products[ $gateway ] ) ) {
|
||||
foreach ( WC()->cart->get_cart() as $item ) {
|
||||
if ( in_array( $item['product_id'], $exclude_products[ $gateway ] ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* gateways_fees.
|
||||
*
|
||||
* @version 3.7.0
|
||||
*/
|
||||
function gateways_fees() {
|
||||
global $woocommerce;
|
||||
$current_gateway = $this->get_current_gateway();
|
||||
if ( '' != $current_gateway ) {
|
||||
$fee_text = get_option( 'wcj_gateways_fees_text_' . $current_gateway );
|
||||
$min_cart_amount = get_option( 'wcj_gateways_fees_min_cart_amount_' . $current_gateway );
|
||||
$max_cart_amount = get_option( 'wcj_gateways_fees_max_cart_amount_' . $current_gateway );
|
||||
// Multicurrency (Currency Switcher) module
|
||||
if ( WCJ()->modules['multicurrency']->is_enabled() ) {
|
||||
$min_cart_amount = WCJ()->modules['multicurrency']->change_price( $min_cart_amount, null );
|
||||
$max_cart_amount = WCJ()->modules['multicurrency']->change_price( $max_cart_amount, null );
|
||||
}
|
||||
$total_in_cart = ( 'no' === get_option( 'wcj_gateways_fees_exclude_shipping_' . $current_gateway, 'no' ) ?
|
||||
$woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total :
|
||||
$woocommerce->cart->cart_contents_total
|
||||
);
|
||||
if ( '' != $fee_text && $total_in_cart >= $min_cart_amount && ( 0 == $max_cart_amount || $total_in_cart <= $max_cart_amount ) && $this->check_cart_products( $current_gateway ) ) {
|
||||
$fee_value = get_option( 'wcj_gateways_fees_value_' . $current_gateway );
|
||||
$fee_type = get_option( 'wcj_gateways_fees_type_' . $current_gateway );
|
||||
$final_fee_to_add = 0;
|
||||
switch ( $fee_type ) {
|
||||
case 'fixed':
|
||||
// Multicurrency (Currency Switcher) module
|
||||
if ( WCJ()->modules['multicurrency']->is_enabled() ) {
|
||||
$fee_value = WCJ()->modules['multicurrency']->change_price( $fee_value, null );
|
||||
}
|
||||
$final_fee_to_add = $fee_value;
|
||||
break;
|
||||
case 'percent':
|
||||
$final_fee_to_add = ( $fee_value / 100 ) * $total_in_cart;
|
||||
if ( 'yes' === get_option( 'wcj_gateways_fees_round_' . $current_gateway ) ) {
|
||||
$final_fee_to_add = round( $final_fee_to_add, get_option( 'wcj_gateways_fees_round_precision_' . $current_gateway ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( 0 != $final_fee_to_add ) {
|
||||
$taxable = ( 'yes' === get_option( 'wcj_gateways_fees_is_taxable_' . $current_gateway ) ) ? true : false;
|
||||
$tax_class_name = '';
|
||||
if ( $taxable ) {
|
||||
$tax_class_id = get_option( 'wcj_gateways_fees_tax_class_id_' . $current_gateway, 0 );
|
||||
$tax_class_names = array_merge( array( '', ), WC_Tax::get_tax_classes() );
|
||||
$tax_class_name = $tax_class_names[ $tax_class_id ];
|
||||
}
|
||||
$woocommerce->cart->add_fee( $fee_text, $final_fee_to_add, $taxable, $tax_class_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Payment_Gateways_Fees();
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Gateways Icons
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.2.2
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Payment_Gateways_Icons' ) ) :
|
||||
|
||||
class WCJ_Payment_Gateways_Icons extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'payment_gateways_icons';
|
||||
$this->short_desc = __( 'Gateways Icons', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Change or completely remove icons (images) for any (default or custom) payment gateway.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-payment-gateways-icons';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_gateway_icon', array( $this, 'set_icon' ), PHP_INT_MAX, 2 );
|
||||
|
||||
// compatibility with 2.3.0 or below
|
||||
$default_gateways = array( 'cod', 'cheque', 'bacs', 'mijireh_checkout', 'paypal' );
|
||||
foreach ( $default_gateways as $key ) {
|
||||
$deprecated_option = get_option( 'wcj_payment_gateways_icons_' . 'woocommerce_' . $key . '_icon', '' );
|
||||
if ( '' != $deprecated_option ) {
|
||||
update_option( 'wcj_gateways_icons_' . $key . '_icon', $deprecated_option );
|
||||
delete_option( 'wcj_payment_gateways_icons_' . 'woocommerce_' . $key . '_icon' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set_icon.
|
||||
*
|
||||
* @version 2.3.1
|
||||
*/
|
||||
function set_icon( $icon, $key ) {
|
||||
$default_gateways = apply_filters( 'booster_option', array( 'cod', 'cheque', 'bacs', 'mijireh_checkout', 'paypal' ), array() );
|
||||
if ( ! empty( $default_gateways ) && ! in_array( $key, $default_gateways ) ) {
|
||||
return $icon;
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_gateways_icons_' . $key . '_icon_remove', 'no' ) ) {
|
||||
return '';
|
||||
}
|
||||
$custom_icon_url = get_option( 'wcj_gateways_icons_' . $key . '_icon', '' );
|
||||
return ( '' == $custom_icon_url ) ? $icon : '<img src="' . $custom_icon_url . '" alt="' . $key . '" />';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Payment_Gateways_Icons();
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Gateways Min/Max Amounts
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @since 2.4.1
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Payment_Gateways_Min_Max' ) ) :
|
||||
|
||||
class WCJ_Payment_Gateways_Min_Max extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.4.1
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'payment_gateways_min_max';
|
||||
$this->short_desc = __( 'Gateways Min/Max Amounts', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add min/max amounts for payment gateways to show up.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-payment-gateways-min-max-amounts';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'woocommerce_available_payment_gateways', array( $this, 'available_payment_gateways' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* available_payment_gateways.
|
||||
*
|
||||
* @version 3.2.3
|
||||
* @since 2.4.1
|
||||
* @todo (maybe) `wc_clear_notices()`
|
||||
*/
|
||||
function available_payment_gateways( $_available_gateways ) {
|
||||
if ( ! function_exists( 'WC' ) || ! isset( WC()->cart ) ) {
|
||||
return $_available_gateways;
|
||||
}
|
||||
$total_in_cart = WC()->cart->cart_contents_total;
|
||||
if ( 'no' === get_option( 'wcj_payment_gateways_min_max_exclude_shipping', 'no' ) ) {
|
||||
$total_in_cart += WC()->cart->shipping_total;
|
||||
}
|
||||
$notices = array();
|
||||
$notices_template_min = get_option( 'wcj_payment_gateways_min_max_notices_template_min', __( 'Minimum amount for %gateway_title% is %min_amount%', 'woocommerce-jetpack') );
|
||||
$notices_template_max = get_option( 'wcj_payment_gateways_min_max_notices_template_max', __( 'Maximum amount for %gateway_title% is %max_amount%', 'woocommerce-jetpack') );
|
||||
foreach ( $_available_gateways as $key => $gateway ) {
|
||||
$min = get_option( 'wcj_payment_gateways_min_' . $key, 0 );
|
||||
$max = get_option( 'wcj_payment_gateways_max_' . $key, 0 );
|
||||
if ( $min != 0 && $total_in_cart < $min ) {
|
||||
$notices[] = str_replace( array( '%gateway_title%', '%min_amount%' ), array( $gateway->title, wc_price( $min ) ), $notices_template_min );
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
if ( $max != 0 && $total_in_cart > $max ) {
|
||||
$notices[] = str_replace( array( '%gateway_title%', '%max_amount%' ), array( $gateway->title, wc_price( $max ) ), $notices_template_max );
|
||||
unset( $_available_gateways[ $key ] );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( function_exists( 'is_checkout' ) && is_checkout() && 'yes' === get_option( 'wcj_payment_gateways_min_max_notices_enable', 'yes' ) && ! empty( $notices ) ) {
|
||||
$notice_type = get_option( 'wcj_payment_gateways_min_max_notices_type', 'notice' );
|
||||
foreach ( $notices as $notice ) {
|
||||
if ( ! wc_has_notice( $notice, $notice_type ) ) {
|
||||
wc_add_notice( $notice, $notice_type );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $_available_gateways;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Payment_Gateways_Min_Max();
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Gateways per Product or Category
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 2.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Payment_Gateways_Per_Category' ) ) :
|
||||
|
||||
class WCJ_Payment_Gateways_Per_Category extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'payment_gateways_per_category';
|
||||
$this->short_desc = __( 'Gateways per Product or Category', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Show payment gateway only if there is selected product or product category in cart.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-payment-gateways-per-product-or-category';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// add_filter( 'woocommerce_payment_gateways_settings', array( $this, 'add_per_category_settings' ), 100 );
|
||||
add_filter( 'woocommerce_available_payment_gateways', array( $this, 'filter_available_payment_gateways_per_category' ), 100 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* filter_available_payment_gateways_per_category.
|
||||
*
|
||||
* @version 3.1.0
|
||||
*/
|
||||
function filter_available_payment_gateways_per_category( $available_gateways ) {
|
||||
|
||||
/*
|
||||
if ( ! is_checkout() ) {
|
||||
return $available_gateways;
|
||||
}
|
||||
*/
|
||||
|
||||
if ( ! isset( WC()->cart ) ) {
|
||||
return $available_gateways;
|
||||
}
|
||||
|
||||
foreach ( $available_gateways as $gateway_id => $gateway ) {
|
||||
|
||||
// Including by categories
|
||||
$categories_in = get_option( 'wcj_gateways_per_category_' . $gateway_id );
|
||||
if ( ! empty( $categories_in ) ) {
|
||||
$do_skip = true;
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
$product_categories = get_the_terms( $values['product_id'], 'product_cat' );
|
||||
if ( empty( $product_categories ) ) {
|
||||
continue; // ... to next product in the cart
|
||||
}
|
||||
foreach( $product_categories as $product_category ) {
|
||||
if ( in_array( $product_category->term_id, $categories_in ) ) {
|
||||
// Current gateway is OK, breaking to check next gateway (no need to check other categories of the product)
|
||||
$do_skip = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! $do_skip ) {
|
||||
// Current gateway is OK, breaking to check next gateway (no need to check other products in the cart)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( $do_skip ) {
|
||||
// Skip (i.e. hide/unset) current gateway - no products of needed categories found in the cart
|
||||
if ( isset( $available_gateways[ $gateway_id ] ) ) {
|
||||
unset( $available_gateways[ $gateway_id ] );
|
||||
}
|
||||
continue; // ... to next gateway
|
||||
}
|
||||
}
|
||||
|
||||
// Excluding by categories
|
||||
$categories_excl = get_option( 'wcj_gateways_per_category_excl_' . $gateway_id );
|
||||
if ( ! empty( $categories_excl ) ) {
|
||||
$do_skip = false;
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
$product_categories = get_the_terms( $values['product_id'], 'product_cat' );
|
||||
if ( empty( $product_categories ) ) {
|
||||
continue; // ... to next product in the cart
|
||||
}
|
||||
foreach( $product_categories as $product_category ) {
|
||||
if ( in_array( $product_category->term_id, $categories_excl ) ) {
|
||||
// Skip (i.e. hide/unset) current gateway
|
||||
if ( isset( $available_gateways[ $gateway_id ] ) ) {
|
||||
unset( $available_gateways[ $gateway_id ] );
|
||||
}
|
||||
$do_skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( $do_skip ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( $do_skip ) {
|
||||
continue; // ... to next gateway
|
||||
}
|
||||
}
|
||||
|
||||
// Including by products
|
||||
$products_in = wcj_maybe_convert_string_to_array( apply_filters( 'booster_option', array(), get_option( 'wcj_gateways_per_products_' . $gateway_id ) ) );
|
||||
if ( ! empty( $products_in ) ) {
|
||||
$do_skip = true;
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
if ( in_array( $values['product_id'], $products_in ) ) {
|
||||
// Current gateway is OK
|
||||
$do_skip = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( $do_skip ) {
|
||||
// Skip (i.e. hide/unset) current gateway
|
||||
if ( isset( $available_gateways[ $gateway_id ] ) ) {
|
||||
unset( $available_gateways[ $gateway_id ] );
|
||||
}
|
||||
continue; // ... to next gateway
|
||||
}
|
||||
}
|
||||
|
||||
// Excluding by products
|
||||
$products_excl = wcj_maybe_convert_string_to_array( apply_filters( 'booster_option', array(), get_option( 'wcj_gateways_per_products_excl_' . $gateway_id ) ) );
|
||||
if ( ! empty( $products_excl ) ) {
|
||||
$do_skip = false;
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
if ( in_array( $values['product_id'], $products_excl ) ) {
|
||||
// Skip (i.e. hide/unset) current gateway
|
||||
if ( isset( $available_gateways[ $gateway_id ] ) ) {
|
||||
unset( $available_gateways[ $gateway_id ] );
|
||||
}
|
||||
$do_skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( $do_skip ) {
|
||||
continue; // ... to next gateway
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $available_gateways;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Payment_Gateways_Per_Category();
|
||||
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Custom Gateways
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Payment_Gateways' ) ) :
|
||||
|
||||
class WCJ_Payment_Gateways extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.3.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'payment_gateways';
|
||||
$this->short_desc = __( 'Custom Gateways', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add multiple custom payment gateways to WooCommerce.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-custom-payment-gateways';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
include_once( 'gateways/class-wc-gateway-wcj-custom.php' );
|
||||
add_action( 'woocommerce_after_checkout_validation', array( $this, 'check_required_wcj_input_fields' ), PHP_INT_MAX, 2 );
|
||||
add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'update_custom_payment_gateways_fields_order_meta' ), PHP_INT_MAX, 2 );
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_custom_payment_gateways_fields_admin_order_meta_box' ) );
|
||||
add_action( 'admin_init', array( $this, 'maybe_delete_payment_gateway_input_fields' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_delete_payment_gateway_input_fields.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
*/
|
||||
function maybe_delete_payment_gateway_input_fields() {
|
||||
if ( isset( $_GET['wcj_delete_payment_gateway_input_fields'] ) ) {
|
||||
$order_id = $_GET['wcj_delete_payment_gateway_input_fields'];
|
||||
delete_post_meta( $order_id, '_wcj_custom_payment_gateway_input_fields' );
|
||||
wp_safe_redirect( remove_query_arg( 'wcj_delete_payment_gateway_input_fields' ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check_required_wcj_input_fields.
|
||||
*
|
||||
* @version 3.0.1
|
||||
* @since 3.0.1
|
||||
*/
|
||||
function check_required_wcj_input_fields( $data, $errors ) {
|
||||
$payment_method = $data['payment_method'];
|
||||
if ( 'jetpack_custom_gateway' === substr( $payment_method, 0, 22 ) ) {
|
||||
foreach ( $_POST as $key => $value ) {
|
||||
if ( 'wcj_input_field_' === substr( $key, 0, 16 ) ) {
|
||||
if ( isset( $_POST[ 'for_' . $key ] ) && $payment_method === $_POST[ 'for_' . $key ] ) {
|
||||
$is_required_set = ( isset( $_POST[ $key . '_required' ] ) && 'yes' === $_POST[ $key . '_required' ] );
|
||||
if ( $is_required_set && '' == $value ) {
|
||||
$label = ( isset( $_POST[ 'label_for_' . $key ] ) ? $_POST[ 'label_for_' . $key ] : substr( $key, 16 ) );
|
||||
$errors->add( 'booster', sprintf( __( '<strong>%s</strong> is a required field.', 'woocommerce-jetpack' ), $label ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_payment_gateways_fields_admin_order_meta_box.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_custom_payment_gateways_fields_admin_order_meta_box() {
|
||||
$order_id = get_the_ID();
|
||||
$input_fields = get_post_meta( $order_id, '_wcj_custom_payment_gateway_input_fields', true );
|
||||
if ( ! empty( $input_fields ) ) {
|
||||
$payment_method_title = get_post_meta( $order_id, '_payment_method_title', true );
|
||||
$screen = 'shop_order';
|
||||
$context = 'side';
|
||||
$priority = 'high';
|
||||
add_meta_box(
|
||||
'wc-jetpack-' . $this->id,
|
||||
__( 'Booster', 'woocommerce-jetpack' ) . ': ' . sprintf( __( '%s Fields', 'woocommerce-jetpack' ), $payment_method_title ),
|
||||
array( $this, 'create_custom_payment_gateways_fields_admin_order_meta_box' ),
|
||||
$screen,
|
||||
$context,
|
||||
$priority
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create_custom_payment_gateways_fields_admin_order_meta_box.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function create_custom_payment_gateways_fields_admin_order_meta_box() {
|
||||
$order_id = get_the_ID();
|
||||
$html = '';
|
||||
$input_fields = get_post_meta( $order_id, '_wcj_custom_payment_gateway_input_fields', true );
|
||||
$table_data = array();
|
||||
foreach ( $input_fields as $name => $value ) {
|
||||
$table_data[] = array( $name, $value );
|
||||
}
|
||||
$html .= wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped', 'table_heading_type' => 'vertical', ) );
|
||||
if ( 'yes' === get_option( 'wcj_custom_payment_gateways_input_fields_delete_button', 'no' ) ) {
|
||||
$html .= '<p><a style="color:#a00;" href="' . add_query_arg( 'wcj_delete_payment_gateway_input_fields', $order_id ) . '"' . wcj_get_js_confirmation() . '>' .
|
||||
__( 'Delete', 'woocommerce-jetpack' ) . '</a></p>';
|
||||
}
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* update_custom_payment_gateways_fields_order_meta.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function update_custom_payment_gateways_fields_order_meta( $order_id, $posted ) {
|
||||
$payment_method = get_post_meta( $order_id, '_payment_method', true );
|
||||
if ( 'jetpack_custom_gateway' === substr( $payment_method, 0, 22 ) ) {
|
||||
$input_fields = array();
|
||||
foreach ( $_POST as $key => $value ) {
|
||||
if ( 'wcj_input_field_' === substr( $key, 0, 16 ) ) {
|
||||
if ( isset( $_POST[ 'for_' . $key ] ) && $payment_method === $_POST[ 'for_' . $key ] ) {
|
||||
if ( isset( $_POST[ 'label_for_' . $key ] ) ) {
|
||||
$input_fields[ $_POST[ 'label_for_' . $key ] ] = $value;
|
||||
} else {
|
||||
$input_fields[ substr( $key, 16 ) ] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! empty( $input_fields ) ) {
|
||||
update_post_meta( $order_id, '_wcj_custom_payment_gateway_input_fields', $input_fields );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Payment_Gateways();
|
||||
@@ -0,0 +1,475 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - PDF Invoicing
|
||||
*
|
||||
* @version 3.5.2
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_PDF_Invoicing' ) ) :
|
||||
|
||||
class WCJ_PDF_Invoicing extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.5.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'pdf_invoicing';
|
||||
$this->short_desc = __( 'PDF Invoicing', 'woocommerce-jetpack' );
|
||||
$this->section_title = __( 'General', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Invoices, Proforma Invoices, Credit Notes and Packing Slips.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-pdf-invoicing-and-packing-slips';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'renumerate_invoices' => array(
|
||||
'title' => __( 'Invoices Renumerate', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Tool renumerates all invoices, proforma invoices, credit notes and packing slips.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'invoices_report' => array(
|
||||
'title' => __( 'Invoices Report', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Invoices Monthly Reports.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
add_action( 'init', array( $this, 'catch_args' ) );
|
||||
add_action( 'init', array( $this, 'generate_pdf_on_init' ) );
|
||||
|
||||
// Bulk actions
|
||||
add_action( 'admin_footer-edit.php', array( $this, 'bulk_actions_pdfs_admin_footer' ) );
|
||||
add_action( 'load-edit.php', array( $this, 'bulk_actions_pdfs' ) );
|
||||
add_action( 'admin_notices', array( $this, 'bulk_actions_pdfs_notices' ) );
|
||||
|
||||
$this->the_pdf_invoicing_report_tool = include_once( 'pdf-invoices/class-wcj-pdf-invoicing-report-tool.php' );
|
||||
|
||||
$invoice_types = wcj_get_enabled_invoice_types();
|
||||
foreach ( $invoice_types as $invoice_type ) {
|
||||
$the_hooks = wcj_get_invoice_create_on( $invoice_type['id'] );
|
||||
foreach ( $the_hooks as $the_hook ) {
|
||||
if ( 'manual' != $the_hook ) {
|
||||
add_action( $the_hook, array( $this, 'create_document_hook' ) );
|
||||
if ( 'woocommerce_new_order' === $the_hook ) {
|
||||
add_action( 'woocommerce_api_create_order', array( $this, 'create_document_hook' ) );
|
||||
add_action( 'woocommerce_cli_create_order', array( $this, 'create_document_hook' ) );
|
||||
add_action( 'kco_before_confirm_order', array( $this, 'create_document_hook' ) );
|
||||
add_action( 'woocommerce_checkout_order_processed', array( $this, 'create_document_hook' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Editable numbers in meta box
|
||||
if ( 'yes' === get_option( 'wcj_invoicing_add_order_meta_box_numbering', 'yes' ) ) {
|
||||
add_action( 'save_post_shop_order', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra bulk action options to generate/download documents.
|
||||
*
|
||||
* Using Javascript until WordPress core fixes: http://core.trac.wordpress.org/ticket/16031
|
||||
*
|
||||
* @see https://www.skyverge.com/blog/add-custom-bulk-action/
|
||||
* @version 3.5.0
|
||||
* @since 2.5.7
|
||||
* @todo add bulk actions in a correct way for newer WP
|
||||
*/
|
||||
function bulk_actions_pdfs_admin_footer() {
|
||||
global $post_type;
|
||||
if ( 'shop_order' == $post_type ) {
|
||||
$invoice_types = wcj_get_enabled_invoice_types();
|
||||
$actions = array(
|
||||
'generate' => __( 'Generate', 'woocommerce-jetpack' ),
|
||||
'download' => __( 'Download (Zip)', 'woocommerce-jetpack' ),
|
||||
'merge' => __( 'Merge (Print)', 'woocommerce-jetpack' ),
|
||||
);
|
||||
$html = '';
|
||||
$html .= '<script type="text/javascript">';
|
||||
foreach ( $actions as $action_id => $action_title ) {
|
||||
foreach ( $invoice_types as $invoice_type ) {
|
||||
$key = $invoice_type['id'];
|
||||
$title = $invoice_type['title'];
|
||||
$html .= 'jQuery(function() { ';
|
||||
foreach ( array( 'action', 'action2' ) as $action ) {
|
||||
$html .= 'jQuery(\'<option>\').' .
|
||||
'val(\''. $action_id . '_' . $key . '\').' .
|
||||
'text(\'' . $action_title . ' ' . $title . '\').' .
|
||||
'appendTo(\'select[name="' . $action . '"]\'); ';
|
||||
}
|
||||
$html .= '}); ';
|
||||
}
|
||||
}
|
||||
$html .= '</script>';
|
||||
echo $html;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* bulk_actions_pdfs_notices.
|
||||
*
|
||||
* @version 3.5.2
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function bulk_actions_pdfs_notices() {
|
||||
global $post_type, $pagenow;
|
||||
if ( $pagenow == 'edit.php' && 'shop_order' == $post_type ) {
|
||||
if ( isset( $_REQUEST['generated'] ) && (int) $_REQUEST['generated'] ) {
|
||||
$message = sprintf( _n( 'Document generated.', '%s documents generated.', $_REQUEST['generated'] ), number_format_i18n( $_REQUEST['generated'] ) );
|
||||
echo "<div class='updated'><p>{$message}</p></div>";
|
||||
}
|
||||
if ( isset( $_GET['wcj_notice'] ) ) {
|
||||
switch ( $_GET['wcj_notice'] ) {
|
||||
case 'ziparchive_class_missing':
|
||||
echo '<div class="notice notice-error"><p><strong>' .
|
||||
sprintf( __( 'Booster: %s class is not accessible on your server. Please contact your hosting provider.', 'woocommerce-jetpack' ),
|
||||
'<a target="_blank" href="http://php.net/manual/en/class.ziparchive.php">PHP ZipArchive</a>' ) .
|
||||
'</strong></p></div>';
|
||||
break;
|
||||
case 'ziparchive_error':
|
||||
echo '<div class="notice notice-error"><p>' .
|
||||
__( 'Booster: ZipArchive error.', 'woocommerce-jetpack' ) .
|
||||
'</p></div>';
|
||||
break;
|
||||
case 'merge_pdfs_no_files':
|
||||
echo '<div class="notice notice-error"><p>' .
|
||||
__( 'Booster: Merge PDFs: No files.', 'woocommerce-jetpack' ) .
|
||||
'</p></div>';
|
||||
break;
|
||||
case 'merge_pdfs_php_version':
|
||||
echo '<div class="notice notice-error"><p>' .
|
||||
sprintf( __( 'Booster: Merge PDFs: Command requires PHP version 5.3.0 at least. You have PHP version %s installed.', 'woocommerce-jetpack' ), PHP_VERSION ) .
|
||||
'</p></div>';
|
||||
break;
|
||||
default:
|
||||
echo '<div class="notice notice-error"><p>' .
|
||||
sprintf( __( 'Booster: %s.', 'woocommerce-jetpack' ), '<code>' . $_GET['wcj_notice'] . '</code>' ) .
|
||||
'</p></div>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* bulk_actions_pdfs.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.5.7
|
||||
* @todo on `generate` (and maybe other actions) validate user permissions/capabilities - `if ( ! current_user_can( $post_type_object->cap->export_post, $post_id ) ) { wp_die( __( 'You are not allowed to export this post.' ) ); }`
|
||||
* @todo add security check - `check_admin_referer( 'bulk-posts' )`
|
||||
*/
|
||||
function bulk_actions_pdfs() {
|
||||
|
||||
// Get the action
|
||||
$wp_list_table = _get_list_table( 'WP_Posts_List_Table' );
|
||||
$action = $wp_list_table->current_action();
|
||||
|
||||
// Validate the action
|
||||
$action_exploded = explode( '_', $action, 2 );
|
||||
if (
|
||||
! isset( $_GET['post'] ) || empty( $action_exploded ) || ! is_array( $action_exploded ) || 2 !== count( $action_exploded ) ||
|
||||
! in_array( $action_exploded[0], array( 'generate', 'download', 'merge' ) )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform the action
|
||||
$post_ids = $_GET['post'];
|
||||
$the_action = $action_exploded[0];
|
||||
$the_type = $action_exploded[1];
|
||||
switch( $the_action ) {
|
||||
case 'generate':
|
||||
$generated = 0;
|
||||
foreach( $post_ids as $post_id ) {
|
||||
if ( $this->create_document( $post_id, $the_type ) ) {
|
||||
$generated++;
|
||||
}
|
||||
}
|
||||
// Build the redirect url
|
||||
$sendback = add_query_arg(
|
||||
array(
|
||||
'post_type' => 'shop_order',
|
||||
'generated' => $generated,
|
||||
'generated_type' => $the_type,
|
||||
'generated_' . $the_type => 1,
|
||||
'ids' => join( ',', $post_ids ),
|
||||
'post_status' => $_GET['post_status'],
|
||||
),
|
||||
$sendback
|
||||
);
|
||||
break;
|
||||
case 'download':
|
||||
if ( '' != ( $result = $this->get_invoices_zip( $the_type, $post_ids ) ) ) {
|
||||
// Build the redirect url
|
||||
$sendback = add_query_arg(
|
||||
array(
|
||||
'post_type' => 'shop_order',
|
||||
'post_status' => $_GET['post_status'],
|
||||
'wcj_notice' => $result,
|
||||
),
|
||||
$sendback
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'merge':
|
||||
$merge_ids = array();
|
||||
foreach( $post_ids as $post_id ) {
|
||||
if ( wcj_is_invoice_created( $post_id, $the_type ) ) {
|
||||
$merge_ids[] = $post_id;
|
||||
}
|
||||
}
|
||||
if ( ! empty( $merge_ids ) ) {
|
||||
if ( '' != ( $result = $this->merge_pdfs( $the_type, $merge_ids ) ) ) {
|
||||
// Build the redirect url
|
||||
$sendback = add_query_arg(
|
||||
array(
|
||||
'post_type' => 'shop_order',
|
||||
'post_status' => $_GET['post_status'],
|
||||
'wcj_notice' => $result,
|
||||
),
|
||||
$sendback
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// Redirect client
|
||||
wp_redirect( esc_url_raw( $sendback ) );
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* merge_pdfs.
|
||||
*
|
||||
* @version 3.5.2
|
||||
* @since 3.5.0
|
||||
* @see https://www.setasign.com/products/fpdi/demos/concatenate-fake/
|
||||
* @todo rethink filename (i.e. 'docs.pdf')
|
||||
* @todo (maybe) always save/download instead of display on output
|
||||
*/
|
||||
function merge_pdfs( $invoice_type_id, $post_ids ) {
|
||||
if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) {
|
||||
return 'merge_pdfs_php_version';
|
||||
}
|
||||
$files = array();
|
||||
foreach( $post_ids as $post_id ) {
|
||||
$the_invoice = wcj_get_pdf_invoice( $post_id, $invoice_type_id );
|
||||
$files[] = $the_invoice->get_pdf( 'F' );
|
||||
}
|
||||
if ( empty( $files ) ) {
|
||||
return 'merge_pdfs_no_files';
|
||||
}
|
||||
require_once( wcj_plugin_path() . '/includes/lib/FPDI/src/autoload.php' );
|
||||
$fpdi_pdf = require_once( wcj_plugin_path() . '/includes/pdf-invoices/tcpdffpdi.php' );
|
||||
$fpdi_pdf->SetTitle( 'docs.pdf' );
|
||||
$fpdi_pdf->setPrintHeader( false );
|
||||
$fpdi_pdf->setPrintFooter( false );
|
||||
foreach( $files as $file ) {
|
||||
$page_count = $fpdi_pdf->setSourceFile( $file );
|
||||
for ( $page_nr = 1; $page_nr <= $page_count; $page_nr++ ) {
|
||||
$page_id = $fpdi_pdf->ImportPage( $page_nr );
|
||||
$s = $fpdi_pdf->getTemplatesize( $page_id );
|
||||
$fpdi_pdf->AddPage( $s['orientation'], $s );
|
||||
$fpdi_pdf->useImportedPage( $page_id );
|
||||
}
|
||||
}
|
||||
$fpdi_pdf->Output( 'docs.pdf', ( 'yes' === get_option( 'wcj_invoicing_' . $invoice_type_id . '_save_as_enabled', 'no' ) ? 'D' : 'I' ) );
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* get_invoices_zip.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.5.7
|
||||
* @todo (maybe) add timestamp to filename
|
||||
* @todo add `ZipArchive` fallback
|
||||
*/
|
||||
function get_invoices_zip( $invoice_type_id, $post_ids ) {
|
||||
if ( ! class_exists( 'ZipArchive' ) ) {
|
||||
return 'ziparchive_class_missing';
|
||||
}
|
||||
// Creating Zip
|
||||
$zip = new ZipArchive();
|
||||
$zip_file_name = $invoice_type_id . '-' .
|
||||
sanitize_title( str_replace( array( 'http://', 'https://' ), '', site_url() ) ) . '-' .
|
||||
min( $post_ids ) . '-' . max( $post_ids ) .
|
||||
'.zip';
|
||||
$zip_file_path = wcj_get_invoicing_temp_dir() . '/' . $zip_file_name;
|
||||
if ( file_exists( $zip_file_path ) ) {
|
||||
@unlink( $zip_file_path );
|
||||
}
|
||||
if ( $zip->open( $zip_file_path, ZipArchive::CREATE | ZIPARCHIVE::OVERWRITE ) !== TRUE ) {
|
||||
return 'ziparchive_error';
|
||||
}
|
||||
foreach( $post_ids as $post_id ) {
|
||||
if ( wcj_is_invoice_created( $post_id, $invoice_type_id ) ) {
|
||||
$the_invoice = wcj_get_pdf_invoice( $post_id, $invoice_type_id );
|
||||
$file_name = $the_invoice->get_pdf( 'F' );
|
||||
$zip->addFile( $file_name, $the_invoice->get_file_name() );
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
// Sending Zip
|
||||
wcj_send_file( $zip_file_name, $zip_file_path, 'zip', true );
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* create_invoices_report_tool.
|
||||
*
|
||||
* @version 2.3.10
|
||||
* @since 2.3.10
|
||||
*/
|
||||
function create_invoices_report_tool() {
|
||||
return $this->the_pdf_invoicing_report_tool->create_invoices_report_tool();
|
||||
}
|
||||
|
||||
/**
|
||||
* create_renumerate_invoices_tool.
|
||||
*
|
||||
* @version 2.3.10
|
||||
* @since 2.3.10
|
||||
*/
|
||||
function create_renumerate_invoices_tool() {
|
||||
$the_tool = include_once( 'pdf-invoices/class-wcj-pdf-invoicing-renumerate-tool.php' );
|
||||
return $the_tool->create_renumerate_invoices_tool();
|
||||
}
|
||||
|
||||
/**
|
||||
* create_document_hook.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function create_document_hook( $order_id ) {
|
||||
$current_filter = current_filter();
|
||||
if ( in_array( $current_filter,
|
||||
array( 'woocommerce_api_create_order', 'woocommerce_cli_create_order', 'kco_before_confirm_order', 'woocommerce_checkout_order_processed' ) )
|
||||
) {
|
||||
$current_filter = 'woocommerce_new_order';
|
||||
}
|
||||
$invoice_types = wcj_get_enabled_invoice_types();
|
||||
foreach ( $invoice_types as $invoice_type ) {
|
||||
$the_hooks = wcj_get_invoice_create_on( $invoice_type['id'] );
|
||||
foreach ( $the_hooks as $the_hook ) {
|
||||
if ( 'manual' != $the_hook ) {
|
||||
if ( $current_filter === $the_hook ) {
|
||||
$this->create_document( $order_id, $invoice_type['id'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create_document.
|
||||
*
|
||||
* @version 2.5.7
|
||||
*/
|
||||
function create_document( $order_id, $invoice_type ) {
|
||||
if ( false == wcj_is_invoice_created( $order_id, $invoice_type ) ) {
|
||||
wcj_create_invoice( $order_id, $invoice_type );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete_document.
|
||||
*
|
||||
* @version 2.3.0
|
||||
* @since 2.3.0
|
||||
*/
|
||||
function delete_document( $order_id, $invoice_type ) {
|
||||
if ( true == wcj_is_invoice_created( $order_id, $invoice_type ) ) {
|
||||
wcj_delete_invoice( $order_id, $invoice_type );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* catch_args.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function catch_args() {
|
||||
$this->order_id = ( isset( $_GET['order_id'] ) ) ? $_GET['order_id'] : 0;
|
||||
$this->invoice_type_id = ( isset( $_GET['invoice_type_id'] ) ) ? $_GET['invoice_type_id'] : '';
|
||||
$this->save_as_pdf = ( isset( $_GET['save_pdf_invoice'] ) && '1' == $_GET['save_pdf_invoice'] );
|
||||
$this->get_invoice = ( isset( $_GET['get_invoice'] ) && '1' == $_GET['get_invoice'] );
|
||||
|
||||
if ( isset( $_GET['create_invoice_for_order_id'] ) && $this->check_user_roles( false ) ) {
|
||||
$this->create_document( $_GET['create_invoice_for_order_id'], $this->invoice_type_id );
|
||||
}
|
||||
if ( isset( $_GET['delete_invoice_for_order_id'] ) && $this->check_user_roles( false ) ) {
|
||||
$this->delete_document( $_GET['delete_invoice_for_order_id'], $this->invoice_type_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check_user_roles.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.9.0
|
||||
* @todo check if `current_user_can( 'administrator' )` is the same as checking role directly
|
||||
*/
|
||||
function check_user_roles( $allow_order_owner = true ) {
|
||||
if ( $allow_order_owner && get_current_user_id() == intval( get_post_meta( $this->order_id, '_customer_user', true ) ) ) {
|
||||
return true;
|
||||
}
|
||||
$allowed_user_roles = get_option( 'wcj_invoicing_' . $this->invoice_type_id . '_roles', array( 'administrator', 'shop_manager' ) );
|
||||
if ( empty( $allowed_user_roles ) ) {
|
||||
$allowed_user_roles = array( 'administrator' );
|
||||
}
|
||||
if ( wcj_is_user_role( $allowed_user_roles ) ) {
|
||||
return true;
|
||||
} else {
|
||||
add_action( 'admin_notices', array( $this, 'wrong_user_role_notice' ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wrong_user_role_notice.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function wrong_user_role_notice() {
|
||||
echo '<div class="notice notice-error is-dismissible"><p>' . __( 'You are not allowed to view the invoice.', 'woocommerce-jetpack' ) . '</p></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* generate_pdf_on_init.
|
||||
*
|
||||
* @version 2.9.0
|
||||
*/
|
||||
function generate_pdf_on_init() {
|
||||
// Check if all is OK
|
||||
if ( true !== $this->get_invoice || 0 == $this->order_id || ! is_user_logged_in() || ! $this->check_user_roles() ) {
|
||||
return;
|
||||
}
|
||||
// Get PDF
|
||||
$the_invoice = wcj_get_pdf_invoice( $this->order_id, $this->invoice_type_id );
|
||||
$dest = ( true === $this->save_as_pdf ? 'D' : 'I' );
|
||||
$the_invoice->get_pdf( $dest );
|
||||
die();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_PDF_Invoicing();
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Prices and Currencies by Country
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Price_By_Country' ) ) :
|
||||
|
||||
class WCJ_Price_By_Country extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.7.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'price_by_country';
|
||||
$this->short_desc = __( 'Prices and Currencies by Country', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Change product price and currency automatically by customer\'s country.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-prices-and-currencies-by-country';
|
||||
parent::__construct();
|
||||
|
||||
global $wcj_notice;
|
||||
$wcj_notice = '';
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
if ( wcj_is_frontend() ) {
|
||||
$do_load_core = true;
|
||||
if ( ! defined( 'DOING_AJAX' ) && '/wc-api/WC_Gateway_Paypal/' == $_SERVER['REQUEST_URI'] ) {
|
||||
// "Wrong currency in emails" bug fix
|
||||
$do_load_core = false;
|
||||
}
|
||||
if ( $do_load_core ) {
|
||||
// Frontend
|
||||
include_once( 'price-by-country/class-wcj-price-by-country-core.php' );
|
||||
}
|
||||
}
|
||||
if ( is_admin() ) {
|
||||
// Backend
|
||||
include_once( 'reports/class-wcj-currency-reports.php' );
|
||||
if ( 'yes' === get_option( 'wcj_price_by_country_local_enabled', 'yes' ) ) {
|
||||
$backend_user_roles = get_option( 'wcj_price_by_country_backend_user_roles', '' );
|
||||
if ( empty( $backend_user_roles ) || wcj_is_user_role( $backend_user_roles ) ) {
|
||||
if ( 'inline' === get_option( 'wcj_price_by_country_local_options_style', 'inline' ) ) {
|
||||
include_once( 'price-by-country/class-wcj-price-by-country-local.php' );
|
||||
} else {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset Price Filter
|
||||
add_action( 'init', array( $this, 'recalculate_price_filter_products_prices' ) );
|
||||
}
|
||||
|
||||
// Price Filter Widget
|
||||
if ( 'yes' === get_option( 'wcj_price_by_country_price_filter_widget_support_enabled', 'no' ) ) {
|
||||
if ( 'yes' === get_option( 'wcj_price_by_country_local_enabled', 'yes' ) ) {
|
||||
add_action( 'save_post_product', array( $this, 'update_products_price_by_country_product_saved' ), PHP_INT_MAX, 2 );
|
||||
add_action( 'woocommerce_ajax_save_product_variations', array( $this, 'update_products_price_by_country_product_saved_ajax' ), PHP_INT_MAX, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Price Filter Widget
|
||||
if ( 'yes' === get_option( 'wcj_price_by_country_price_filter_widget_support_enabled', 'no' ) ) {
|
||||
add_action( 'woojetpack_after_settings_save', array( $this, 'update_products_price_by_country_module_saved' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
if ( is_admin() ) {
|
||||
include_once( 'price-by-country/class-wcj-price-by-country-group-generator.php' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* recalculate_price_filter_products_prices.
|
||||
*
|
||||
* @version 2.5.6
|
||||
* @since 2.5.6
|
||||
*/
|
||||
function recalculate_price_filter_products_prices() {
|
||||
if ( isset( $_GET['recalculate_price_filter_products_prices'] ) && ( wcj_is_user_role( 'administrator' ) || is_shop_manager() ) ) {
|
||||
wcj_update_products_price_by_country();
|
||||
global $wcj_notice;
|
||||
$wcj_notice = __( 'Price filter widget product prices recalculated.', 'woocommerce-jetpack' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update_products_price_by_country_module_saved.
|
||||
*
|
||||
* @version 2.5.3
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function update_products_price_by_country_module_saved( $all_sections, $current_section ) {
|
||||
if ( 'price_by_country' === $current_section && wcj_is_module_enabled( 'price_by_country' ) ) {
|
||||
wcj_update_products_price_by_country();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update_products_price_by_country_product_saved_ajax.
|
||||
*
|
||||
* @version 2.5.3
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function update_products_price_by_country_product_saved_ajax( $post_id ) {
|
||||
wcj_update_products_price_by_country_for_single_product( $post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* update_products_price_by_country_product_saved.
|
||||
*
|
||||
* @version 2.5.3
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function update_products_price_by_country_product_saved( $post_id, $post ) {
|
||||
wcj_update_products_price_by_country_for_single_product( $post_id );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Price_By_Country();
|
||||
@@ -0,0 +1,397 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Price based on User Role
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.0
|
||||
* @author Algoritmika Ltd.
|
||||
* @todo Fix "Make Empty Price" option for variable products
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Price_By_User_Role' ) ) :
|
||||
|
||||
class WCJ_Price_By_User_Role extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'price_by_user_role';
|
||||
$this->short_desc = __( 'Price based on User Role', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Display products prices by user roles.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-price-by-user-role';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
$this->price_hooks_priority = wcj_get_module_price_hooks_priority( 'price_by_user_role' );
|
||||
if ( 'yes' === get_option( 'wcj_price_by_user_role_per_product_enabled', 'yes' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
if ( wcj_is_frontend() ) {
|
||||
if ( 'no' === get_option( 'wcj_price_by_user_role_for_bots_disabled', 'no' ) || ! wcj_is_bot() ) {
|
||||
wcj_add_change_price_hooks( $this, $this->price_hooks_priority );
|
||||
if ( ( $this->disable_for_regular_price = ( 'yes' === get_option( 'wcj_price_by_user_role_disable_for_regular_price', 'no' ) ) ) ) {
|
||||
add_filter( 'woocommerce_product_is_on_sale', array( $this, 'maybe_make_on_sale' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_value' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
||||
// Admin settings - "copy price" buttons
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_script' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_admin_settings_copy_link.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function get_admin_settings_copy_link( $action, $regular_or_sale, $source_product, $source_role, $dest_roles, $dest_products ) {
|
||||
switch ( $action ) {
|
||||
case 'copy_to_roles_and_variations':
|
||||
$dashicon = 'links';
|
||||
$title = __( 'user roles & variations', 'woocommerce-jetpack' );
|
||||
break;
|
||||
case 'copy_to_variations':
|
||||
$dashicon = 'page';
|
||||
$title = __( 'variations', 'woocommerce-jetpack' );
|
||||
break;
|
||||
default: // 'copy_to_roles'
|
||||
$dashicon = 'users';
|
||||
$title = __( 'user roles', 'woocommerce-jetpack' );
|
||||
break;
|
||||
}
|
||||
$data_array = array(
|
||||
'action' => $action,
|
||||
'price' => $regular_or_sale,
|
||||
'source_product' => $source_product,
|
||||
'source_role' => $source_role,
|
||||
'dest_roles' => $dest_roles,
|
||||
'dest_products' => $dest_products,
|
||||
);
|
||||
return '<a href="#" class="wcj-copy-price" wcj-copy-data=\'' . json_encode( $data_array ) . '\'>' .
|
||||
'<span class="dashicons dashicons-admin-' . $dashicon . '" style="font-size:small;float:right;" title="' .
|
||||
sprintf( __( 'Copy price to all %s', 'woocommerce-jetpack' ), $title ) . '">' .
|
||||
'</span>' .
|
||||
'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_admin_script.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function enqueue_admin_script() {
|
||||
wp_enqueue_script( 'wcj-price-by-user-role-admin', wcj_plugin_url() . '/includes/js/wcj-price-by-user-role-admin.js', array( 'jquery' ), WCJ()->version, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_make_on_sale.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 3.2.0
|
||||
*/
|
||||
function maybe_make_on_sale( $on_sale, $product ) {
|
||||
return ( $product->get_price() < $product->get_regular_price() ? true : $on_sale );
|
||||
}
|
||||
|
||||
/**
|
||||
* save_meta_box_value.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function save_meta_box_value( $option_value, $option_name, $module_id ) {
|
||||
if ( true === apply_filters( 'booster_option', false, true ) ) {
|
||||
return $option_value;
|
||||
}
|
||||
if ( 'no' === $option_value ) {
|
||||
return $option_value;
|
||||
}
|
||||
if ( $this->id === $module_id && 'wcj_price_by_user_role_per_product_settings_enabled' === $option_name ) {
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => 1,
|
||||
'meta_key' => '_' . 'wcj_price_by_user_role_per_product_settings_enabled',
|
||||
'meta_value' => 'yes',
|
||||
'post__not_in' => array( get_the_ID() ),
|
||||
);
|
||||
$loop = new WP_Query( $args );
|
||||
$c = $loop->found_posts + 1;
|
||||
if ( $c >= 2 ) {
|
||||
add_filter( 'redirect_post_location', array( $this, 'add_notice_query_var' ), 99 );
|
||||
return 'no';
|
||||
}
|
||||
}
|
||||
return $option_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_notice_query_var.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_notice_query_var( $location ) {
|
||||
remove_filter( 'redirect_post_location', array( $this, 'add_notice_query_var' ), 99 );
|
||||
return add_query_arg( array( 'wcj_product_price_by_user_role_admin_notice' => true ), $location );
|
||||
}
|
||||
|
||||
/**
|
||||
* admin_notices.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function admin_notices() {
|
||||
if ( ! isset( $_GET['wcj_product_price_by_user_role_admin_notice'] ) ) {
|
||||
return;
|
||||
}
|
||||
?><div class="error"><p><?php
|
||||
echo '<div class="message">'
|
||||
. __( 'Booster: Free plugin\'s version is limited to only one price by user role per products settings product enabled at a time. You will need to get <a href="https://booster.io/plus/" target="_blank">Booster Plus</a> to add unlimited number of price by user role per product settings products.', 'woocommerce-jetpack' )
|
||||
. '</div>';
|
||||
?></p></div><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_shipping.
|
||||
*
|
||||
* @version 3.2.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function change_price_shipping( $package_rates, $package ) {
|
||||
if ( 'yes' === get_option( 'wcj_price_by_user_role_shipping_enabled', 'no' ) ) {
|
||||
$current_user_role = wcj_get_current_user_first_role();
|
||||
$koef = get_option( 'wcj_price_by_user_role_' . $current_user_role, 1 );
|
||||
return wcj_change_price_shipping_package_rates( $package_rates, $koef );
|
||||
}
|
||||
return $package_rates;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_grouped.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function change_price_grouped( $price, $qty, $_product ) {
|
||||
if ( $_product->is_type( 'grouped' ) ) {
|
||||
if ( 'yes' === get_option( 'wcj_price_by_user_role_per_product_enabled', 'yes' ) ) {
|
||||
foreach ( $_product->get_children() as $child_id ) {
|
||||
$the_price = get_post_meta( $child_id, '_price', true );
|
||||
$the_product = wc_get_product( $child_id );
|
||||
$the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
|
||||
if ( $the_price == $price ) {
|
||||
return $this->change_price( $price, $the_product );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return $this->change_price( $price, null );
|
||||
}
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.0
|
||||
* @todo (maybe) add "enable compound multipliers" option
|
||||
* @todo (maybe) check for `( '' === $price )` only once, at the beginning of the function (instead of comparing before each `return`)
|
||||
* @todo (maybe) code refactoring (cats/tags)
|
||||
*/
|
||||
function change_price( $price, $_product ) {
|
||||
|
||||
$current_user_role = wcj_get_current_user_first_role();
|
||||
$_current_filter = current_filter();
|
||||
|
||||
if ( ! apply_filters( 'wcj_price_by_user_role_do_change_price', true, $price, $_product, $current_user_role, $_current_filter ) ) {
|
||||
return $price;
|
||||
}
|
||||
|
||||
if ( 'yes' === get_option( 'wcj_price_by_user_role_check_for_product_changes_price', 'no' ) && $_product ) {
|
||||
$product_changes = $_product->get_changes();
|
||||
if ( ! empty( $product_changes ) && isset( $product_changes['price'] ) ) {
|
||||
return $price;
|
||||
}
|
||||
}
|
||||
|
||||
// Per product
|
||||
if ( 'yes' === get_option( 'wcj_price_by_user_role_per_product_enabled', 'yes' ) ) {
|
||||
if ( 'yes' === get_post_meta( wcj_maybe_get_product_id_wpml( wcj_get_product_id_or_variation_parent_id( $_product ) ), '_' . 'wcj_price_by_user_role_per_product_settings_enabled', true ) ) {
|
||||
$_product_id = wcj_maybe_get_product_id_wpml( wcj_get_product_id( $_product ) );
|
||||
if ( 'yes' === get_post_meta( $_product_id, '_' . 'wcj_price_by_user_role_empty_price_' . $current_user_role, true ) ) {
|
||||
return '';
|
||||
}
|
||||
if ( 'multiplier' === get_option( 'wcj_price_by_user_role_per_product_type', 'fixed' ) ) {
|
||||
if ( '' !== ( $multiplier_per_product = get_post_meta( $_product_id, '_' . 'wcj_price_by_user_role_multiplier_' . $current_user_role, true ) ) ) {
|
||||
// Maybe disable for regular price hooks
|
||||
if ( $this->disable_for_regular_price && in_array( $_current_filter, array(
|
||||
WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER,
|
||||
'woocommerce_variation_prices_regular_price',
|
||||
'woocommerce_product_variation_get_regular_price'
|
||||
) ) ) {
|
||||
return $price;
|
||||
}
|
||||
return ( '' === $price ) ? $price : $price * $multiplier_per_product;
|
||||
}
|
||||
} elseif ( '' != ( $regular_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_price_by_user_role_regular_price_' . $current_user_role, true ) ) ) {
|
||||
if ( in_array( $_current_filter, array(
|
||||
'woocommerce_get_price_including_tax',
|
||||
'woocommerce_get_price_excluding_tax'
|
||||
) ) ) {
|
||||
return wcj_get_product_display_price( $_product );
|
||||
} elseif ( in_array( $_current_filter, array(
|
||||
WCJ_PRODUCT_GET_PRICE_FILTER,
|
||||
'woocommerce_variation_prices_price',
|
||||
'woocommerce_product_variation_get_price'
|
||||
) ) ) {
|
||||
$sale_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_price_by_user_role_sale_price_' . $current_user_role, true );
|
||||
$return = ( '' != $sale_price_per_product && $sale_price_per_product < $regular_price_per_product ) ? $sale_price_per_product : $regular_price_per_product;
|
||||
return apply_filters( 'wcj_price_by_user_role_get_price', $return, $_product );
|
||||
} elseif ( in_array( $_current_filter, array(
|
||||
WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER,
|
||||
'woocommerce_variation_prices_regular_price',
|
||||
'woocommerce_product_variation_get_regular_price'
|
||||
) ) ) {
|
||||
return $regular_price_per_product;
|
||||
} elseif ( in_array( $_current_filter, array(
|
||||
WCJ_PRODUCT_GET_SALE_PRICE_FILTER,
|
||||
'woocommerce_variation_prices_sale_price',
|
||||
'woocommerce_product_variation_get_sale_price'
|
||||
) ) ) {
|
||||
$sale_price_per_product = get_post_meta( $_product_id, '_' . 'wcj_price_by_user_role_sale_price_' . $current_user_role, true );
|
||||
return ( '' != $sale_price_per_product ) ? $sale_price_per_product : $price;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe disable for products on sale
|
||||
if ( 'yes' === get_option( 'wcj_price_by_user_role_disable_for_products_on_sale', 'no' ) ) {
|
||||
wcj_remove_change_price_hooks( $this, $this->price_hooks_priority );
|
||||
if ( $_product && $_product->is_on_sale() ) {
|
||||
wcj_add_change_price_hooks( $this, $this->price_hooks_priority );
|
||||
return $price;
|
||||
} else {
|
||||
wcj_add_change_price_hooks( $this, $this->price_hooks_priority );
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe disable for regular price hooks
|
||||
if ( $this->disable_for_regular_price && in_array( $_current_filter, array(
|
||||
WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER,
|
||||
'woocommerce_variation_prices_regular_price',
|
||||
'woocommerce_product_variation_get_regular_price'
|
||||
) ) ) {
|
||||
return $price;
|
||||
}
|
||||
|
||||
// By category
|
||||
$categories = apply_filters( 'booster_option', '', get_option( 'wcj_price_by_user_role_categories', '' ) );
|
||||
if ( ! empty( $categories ) ) {
|
||||
$product_categories = get_the_terms( wcj_maybe_get_product_id_wpml( wcj_get_product_id_or_variation_parent_id( $_product ) ), 'product_cat' );
|
||||
if ( ! empty( $product_categories ) ) {
|
||||
foreach ( $product_categories as $product_category ) {
|
||||
foreach ( $categories as $category ) {
|
||||
if ( $product_category->term_id == $category ) {
|
||||
if ( 'yes' === get_option( 'wcj_price_by_user_role_cat_empty_price_' . $category . '_' . $current_user_role, 'no' ) ) {
|
||||
return '';
|
||||
}
|
||||
if ( ( $koef_category = get_option( 'wcj_price_by_user_role_cat_' . $category . '_' . $current_user_role, -1 ) ) >= 0 ) {
|
||||
return ( '' === $price ) ? $price : $price * $koef_category;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// By tag
|
||||
$tags = apply_filters( 'booster_option', '', get_option( 'wcj_price_by_user_role_tags', '' ) );
|
||||
if ( ! empty( $tags ) ) {
|
||||
$product_tags = get_the_terms( wcj_maybe_get_product_id_wpml( wcj_get_product_id_or_variation_parent_id( $_product ) ), 'product_tag' );
|
||||
if ( ! empty( $product_tags ) ) {
|
||||
foreach ( $product_tags as $product_tag ) {
|
||||
foreach ( $tags as $tag ) {
|
||||
if ( $product_tag->term_id == $tag ) {
|
||||
if ( 'yes' === get_option( 'wcj_price_by_user_role_tag_empty_price_' . $tag . '_' . $current_user_role, 'no' ) ) {
|
||||
return '';
|
||||
}
|
||||
if ( ( $koef_tag = get_option( 'wcj_price_by_user_role_tag_' . $tag . '_' . $current_user_role, -1 ) ) >= 0 ) {
|
||||
return ( '' === $price ) ? $price : $price * $koef_tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Global
|
||||
if ( 'yes' === get_option( 'wcj_price_by_user_role_empty_price_' . $current_user_role, 'no' ) ) {
|
||||
return '';
|
||||
}
|
||||
if ( 1 != ( $koef = get_option( 'wcj_price_by_user_role_' . $current_user_role, 1 ) ) ) {
|
||||
return ( '' === $price ) ? $price : $price * $koef;
|
||||
}
|
||||
|
||||
// No changes
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_variation_prices_hash.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.0
|
||||
* @todo only hash categories that is relevant to the product
|
||||
* @todo (maybe) code refactoring (cats/tags)
|
||||
*/
|
||||
function get_variation_prices_hash( $price_hash, $_product, $display ) {
|
||||
$user_role = wcj_get_current_user_first_role();
|
||||
$categories = apply_filters( 'booster_option', '', get_option( 'wcj_price_by_user_role_categories', '' ) );
|
||||
$tags = apply_filters( 'booster_option', '', get_option( 'wcj_price_by_user_role_tags', '' ) );
|
||||
$price_hash['wcj_user_role'] = array(
|
||||
$user_role,
|
||||
get_option( 'wcj_price_by_user_role_' . $user_role, 1 ),
|
||||
get_option( 'wcj_price_by_user_role_empty_price_' . $user_role, 'no' ),
|
||||
get_option( 'wcj_price_by_user_role_per_product_enabled', 'yes' ),
|
||||
get_option( 'wcj_price_by_user_role_per_product_type', 'fixed' ),
|
||||
get_option( 'wcj_price_by_user_role_disable_for_products_on_sale', 'no' ),
|
||||
$this->disable_for_regular_price,
|
||||
$categories,
|
||||
$tags,
|
||||
);
|
||||
if ( ! empty( $categories ) ) {
|
||||
foreach ( $categories as $category ) {
|
||||
$price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_cat_empty_price_' . $category . '_' . $user_role, 'no' );
|
||||
$price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_cat_' . $category . '_' . $user_role, -1 );
|
||||
}
|
||||
}
|
||||
if ( ! empty( $tags ) ) {
|
||||
foreach ( $tags as $tag ) {
|
||||
$price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_tag_empty_price_' . $tag . '_' . $user_role, 'no' );
|
||||
$price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_tag_' . $tag . '_' . $user_role, -1 );
|
||||
}
|
||||
}
|
||||
return $price_hash;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Price_By_User_Role();
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Price Formats
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.5.2
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Price_Formats' ) ) :
|
||||
|
||||
class WCJ_Price_Formats extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'price_formats';
|
||||
$this->short_desc = __( 'Price Formats', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set different price formats for different currencies. Set general price format options.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-price-formats';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// Trim Zeros
|
||||
if ( 'yes' === get_option( 'wcj_price_formats_general_trim_zeros', 'no' ) ) {
|
||||
add_filter( 'woocommerce_price_trim_zeros', '__return_true', PHP_INT_MAX );
|
||||
}
|
||||
// Price Formats by Currency (or WPML)
|
||||
if ( 'yes' === get_option( 'wcj_price_formats_by_currency_enabled', 'yes' ) ) {
|
||||
add_filter( 'wc_price_args', array( $this, 'price_format' ), PHP_INT_MAX );
|
||||
add_action( 'init', array( $this, 'add_hooks' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_hooks.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function add_hooks() {
|
||||
add_filter( 'wc_get_price_decimals', array( $this, 'price_decimals' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
/**
|
||||
* price_decimals.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
* @todo code refactoring
|
||||
*/
|
||||
function price_decimals( $price_decimals_num ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_price_formats_total_number', 1 ) ); $i++ ) {
|
||||
if ( get_woocommerce_currency() === get_option( 'wcj_price_formats_currency_' . $i ) ) {
|
||||
if ( defined( 'ICL_LANGUAGE_CODE' ) && '' != ( $wpml_language = get_option( 'wcj_price_formats_wpml_language_' . $i, '' ) ) ) {
|
||||
$wpml_language = explode( ',', trim( str_replace( ' ', '', $wpml_language ), ',' ) );
|
||||
if ( ! in_array( ICL_LANGUAGE_CODE, $wpml_language ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$price_decimals_num = get_option( 'wcj_price_formats_number_of_decimals_' . $i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $price_decimals_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* price_format.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function price_format( $args ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_price_formats_total_number', 1 ) ); $i++ ) {
|
||||
if ( get_woocommerce_currency() === get_option( 'wcj_price_formats_currency_' . $i ) ) {
|
||||
if ( defined( 'ICL_LANGUAGE_CODE' ) && '' != ( $wpml_language = get_option( 'wcj_price_formats_wpml_language_' . $i, '' ) ) ) {
|
||||
$wpml_language = explode( ',', trim( str_replace( ' ', '', $wpml_language ), ',' ) );
|
||||
if ( ! in_array( ICL_LANGUAGE_CODE, $wpml_language ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$args['price_format'] = $this->get_woocommerce_price_format( get_option( 'wcj_price_formats_currency_position_' . $i ) );
|
||||
$args['price_format'] = $this->get_woocommerce_price_format_currency_code(
|
||||
get_option( 'wcj_price_formats_currency_code_position_' . $i, 'none' ), get_option( 'wcj_price_formats_currency_' . $i ), $args['price_format'] );
|
||||
$args['decimal_separator'] = get_option( 'wcj_price_formats_decimal_separator_' . $i );
|
||||
$args['thousand_separator'] = get_option( 'wcj_price_formats_thousand_separator_' . $i );
|
||||
$args['decimals'] = absint( get_option( 'wcj_price_formats_number_of_decimals_' . $i ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_woocommerce_price_format_currency_code.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function get_woocommerce_price_format_currency_code( $currency_code_pos, $currency, $price_format ) {
|
||||
switch ( $currency_code_pos ) {
|
||||
case 'left' :
|
||||
return $currency . $price_format;
|
||||
case 'right' :
|
||||
return $price_format . $currency;
|
||||
case 'left_space' :
|
||||
return $currency . ' ' . $price_format;
|
||||
case 'right_space' :
|
||||
return $price_format . ' ' . $currency;
|
||||
default: // 'none'
|
||||
return $price_format;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_woocommerce_price_format.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function get_woocommerce_price_format( $currency_pos ) {
|
||||
$format = '%1$s%2$s';
|
||||
|
||||
switch ( $currency_pos ) {
|
||||
case 'left' :
|
||||
$format = '%1$s%2$s';
|
||||
break;
|
||||
case 'right' :
|
||||
$format = '%2$s%1$s';
|
||||
break;
|
||||
case 'left_space' :
|
||||
$format = '%1$s %2$s';
|
||||
break;
|
||||
case 'right_space' :
|
||||
$format = '%2$s %1$s';
|
||||
break;
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_price_format', $format, $currency_pos );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Price_Formats();
|
||||
@@ -0,0 +1,409 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Custom Price Labels
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Price_Labels' ) ) :
|
||||
|
||||
class WCJ_Price_Labels extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.3
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'price_labels';
|
||||
$this->short_desc = __( 'Custom Price Labels', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Create any custom price label for any product.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-custom-price-labels';
|
||||
parent::__construct();
|
||||
|
||||
// Custom Price Labels - fields array
|
||||
$this->custom_tab_group_name = 'wcj_price_labels'; // for compatibility with Custom Price Label Pro plugin should use 'simple_is_custom_pricing_label'
|
||||
$this->custom_tab_sections = array( '_instead', '_before', '_between', '_after', );
|
||||
$this->custom_tab_sections_titles = array(
|
||||
'_instead' => __( 'Instead of the price', 'woocommerce-jetpack' ), // for compatibility with Custom Price Label Pro plugin should use ''
|
||||
'_before' => __( 'Before the price', 'woocommerce-jetpack' ),
|
||||
'_between' => __( 'Between regular and sale prices', 'woocommerce-jetpack' ),
|
||||
'_after' => __( 'After the price', 'woocommerce-jetpack' ),
|
||||
);
|
||||
$this->custom_tab_section_variations = array( '_text', '_enabled', '_home', '_products', '_single', '_page', '_cart', /*'_simple',*/ '_variable', '_variation', /*'_grouped',*/ );
|
||||
$this->custom_tab_section_variations_titles = array(
|
||||
'_text' => '', // 'The label',
|
||||
'_enabled' => __( 'Enable', 'woocommerce-jetpack' ), // for compatibility with Custom Price Label Pro plugin should use ''
|
||||
'_home' => __( 'Hide on home page', 'woocommerce-jetpack' ),
|
||||
'_products' => __( 'Hide on products page', 'woocommerce-jetpack' ),
|
||||
'_single' => __( 'Hide on single', 'woocommerce-jetpack' ),
|
||||
'_page' => __( 'Hide on all pages', 'woocommerce-jetpack' ),
|
||||
'_cart' => __( 'Hide on cart page only', 'woocommerce-jetpack' ),
|
||||
// '_simple' => __( 'Hide for simple product', 'woocommerce-jetpack' ),
|
||||
'_variable' => __( 'Hide for main price', 'woocommerce-jetpack' ),
|
||||
'_variation' => __( 'Hide for all variations', 'woocommerce-jetpack' ),
|
||||
// '_grouped' => __( 'Hide for grouped product', 'woocommerce-jetpack' ),
|
||||
);
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
if ( 'yes' === get_option( 'wcj_local_price_labels_enabled', 'yes' ) ) {
|
||||
// Meta box (admin)
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_price_label_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_custom_price_labels' ), 999, 2 );
|
||||
}
|
||||
|
||||
// Prices Hooks
|
||||
$this->prices_filters = array(
|
||||
// Cart
|
||||
'woocommerce_cart_item_price',
|
||||
// Composite Products
|
||||
'woocommerce_composite_sale_price_html',
|
||||
'woocommerce_composite_price_html',
|
||||
'woocommerce_composite_empty_price_html',
|
||||
'woocommerce_composite_free_sale_price_html',
|
||||
'woocommerce_composite_free_price_html',
|
||||
// Booking Products
|
||||
'woocommerce_get_price_html',
|
||||
// Simple Products
|
||||
'woocommerce_empty_price_html',
|
||||
'woocommerce_free_price_html',
|
||||
'woocommerce_free_sale_price_html',
|
||||
'woocommerce_price_html',
|
||||
'woocommerce_sale_price_html',
|
||||
// Grouped Products
|
||||
'woocommerce_grouped_price_html',
|
||||
// Variable Products
|
||||
'woocommerce_variable_empty_price_html',
|
||||
'woocommerce_variable_free_price_html',
|
||||
'woocommerce_variable_free_sale_price_html',
|
||||
'woocommerce_variable_price_html',
|
||||
'woocommerce_variable_sale_price_html',
|
||||
// Variable Products - Variations
|
||||
'woocommerce_variation_empty_price_html',
|
||||
'woocommerce_variation_free_price_html',
|
||||
'woocommerce_variation_price_html',
|
||||
'woocommerce_variation_sale_price_html',
|
||||
// WooCommerce Subscription
|
||||
'woocommerce_subscriptions_product_price_string',
|
||||
'woocommerce_variable_subscription_price_html',
|
||||
// Entrada theme
|
||||
'entrada_price',
|
||||
);
|
||||
foreach ( $this->prices_filters as $the_filter ) {
|
||||
add_filter( $the_filter, array( $this, 'custom_price' ), 100, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* save_custom_price_labels.
|
||||
*/
|
||||
function save_custom_price_labels( $post_id, $post ) {
|
||||
if ( ! isset( $_POST['woojetpack_price_labels_save_post'] ) ) {
|
||||
return;
|
||||
}
|
||||
foreach ( $this->custom_tab_sections as $custom_tab_section ) {
|
||||
foreach ( $this->custom_tab_section_variations as $custom_tab_section_variation ) {
|
||||
$option_name = $this->custom_tab_group_name . $custom_tab_section . $custom_tab_section_variation;
|
||||
if ( $custom_tab_section_variation == '_text' ) {
|
||||
if ( isset( $_POST[ $option_name ] ) ) {
|
||||
update_post_meta( $post_id, '_' . $option_name, $_POST[ $option_name ] );
|
||||
}
|
||||
} else {
|
||||
if ( isset( $_POST[ $option_name ] ) ) {
|
||||
update_post_meta( $post_id, '_' . $option_name, $_POST[ $option_name ] );
|
||||
} else {
|
||||
update_post_meta( $post_id, '_' . $option_name, 'off' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_price_label_meta_box.
|
||||
*
|
||||
* @version 2.4.8
|
||||
*/
|
||||
function add_price_label_meta_box() {
|
||||
add_meta_box(
|
||||
'wc-jetpack-price-labels',
|
||||
__( 'Booster: Custom Price Labels', 'woocommerce-jetpack' ),
|
||||
array( $this, 'create_price_label_meta_box' ),
|
||||
'product',
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* create_price_label_meta_box - back end.
|
||||
*
|
||||
* @version 2.4.8
|
||||
*/
|
||||
function create_price_label_meta_box() {
|
||||
$current_post_id = get_the_ID();
|
||||
echo '<table style="width:100%;">';
|
||||
echo '<tr>';
|
||||
foreach ( $this->custom_tab_sections as $custom_tab_section ) {
|
||||
echo '<td style="width:25%;"><h4>' . $this->custom_tab_sections_titles[ $custom_tab_section ] . '</h4></td>';
|
||||
}
|
||||
echo '</tr>';
|
||||
echo '<tr>';
|
||||
foreach ( $this->custom_tab_sections as $custom_tab_section ) {
|
||||
echo '<td style="width:25%;">';
|
||||
echo '<ul>';
|
||||
foreach ( $this->custom_tab_section_variations as $custom_tab_section_variation ) {
|
||||
$option_name = $this->custom_tab_group_name . $custom_tab_section . $custom_tab_section_variation;
|
||||
if ( $custom_tab_section_variation == '_text' ) {
|
||||
if ( $custom_tab_section != '_instead' ) {
|
||||
$disabled_if_no_plus = apply_filters( 'booster_message', '', 'readonly_string' );
|
||||
} else {
|
||||
$disabled_if_no_plus = '';
|
||||
}
|
||||
$label_text = get_post_meta( $current_post_id, '_' . $option_name, true );
|
||||
$label_text = str_replace ( '"', '"', $label_text );
|
||||
echo '<li>' . $this->custom_tab_section_variations_titles[ $custom_tab_section_variation ] . '<textarea style="width:95%;min-width:100px;height:100px;" ' . $disabled_if_no_plus . ' name="' . $option_name . '">' . $label_text . '</textarea></li>';
|
||||
} else {
|
||||
if ( '_home' === $custom_tab_section_variation ) {
|
||||
echo '<li><h5>Hide by page type</h5></li>';
|
||||
}
|
||||
if ( '_variable' === $custom_tab_section_variation ) {
|
||||
echo '<li><h5>Variable products</h5></li>';
|
||||
}
|
||||
if ( '_instead' != $custom_tab_section ) {
|
||||
$disabled_if_no_plus = apply_filters( 'booster_message', '', 'disabled_string' );
|
||||
} else {
|
||||
$disabled_if_no_plus = '';
|
||||
}
|
||||
echo '<li><input class="checkbox" type="checkbox" ' . $disabled_if_no_plus . ' name="' . $option_name . '" id="' . $option_name . '" ' .
|
||||
checked( get_post_meta( $current_post_id, '_' . $option_name, true ), 'on', false ) . ' /> ' . $this->custom_tab_section_variations_titles[ $custom_tab_section_variation ] . '</li>';
|
||||
}
|
||||
}
|
||||
echo '</ul>';
|
||||
echo '</td>';
|
||||
}
|
||||
echo '</tr>';
|
||||
echo '<tr>';
|
||||
foreach ( $this->custom_tab_sections as $custom_tab_section ) {
|
||||
if ( '_instead' != $custom_tab_section )
|
||||
$disabled_if_no_plus = apply_filters( 'booster_message', '', 'desc_above' );
|
||||
else
|
||||
$disabled_if_no_plus = '';
|
||||
echo '<td style="width:25%;">' . $disabled_if_no_plus . '</td>';
|
||||
}
|
||||
echo '</tr>';
|
||||
echo '</table>';
|
||||
echo '<input type="hidden" name="woojetpack_price_labels_save_post" value="woojetpack_price_labels_save_post">';
|
||||
}
|
||||
|
||||
/*
|
||||
* customize_price.
|
||||
*
|
||||
* @todo recheck if `str_replace( 'From: ', '', $price );` is necessary? Also this works only for English WP installs.
|
||||
*/
|
||||
function customize_price( $price, $custom_tab_section, $custom_label ) {
|
||||
switch ( $custom_tab_section ) {
|
||||
case '_instead':
|
||||
$price = $custom_label;
|
||||
break;
|
||||
case '_before':
|
||||
$price = apply_filters( 'booster_option', $price, $custom_label . $price );
|
||||
break;
|
||||
case '_between':
|
||||
$price = apply_filters( 'booster_option', $price, str_replace( '</del> <ins>', '</del>' . $custom_label . '<ins>', $price ) );
|
||||
break;
|
||||
case '_after':
|
||||
$price = apply_filters( 'booster_option', $price, $price . $custom_label );
|
||||
break;
|
||||
}
|
||||
return str_replace( 'From: ', '', $price );
|
||||
}
|
||||
|
||||
/*
|
||||
* custom_price - front end.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @todo rewrite this with less filters (e.g. `woocommerce_get_price_html` only) - at least for `! WCJ_IS_WC_VERSION_BELOW_3`
|
||||
*/
|
||||
function custom_price( $price, $product ) {
|
||||
|
||||
if ( ! wcj_is_frontend() ) {
|
||||
return $price;
|
||||
}
|
||||
$current_filter_name = current_filter();
|
||||
if ( 'woocommerce_cart_item_price' === $current_filter_name ) {
|
||||
$product = $product['data'];
|
||||
} elseif ( 'entrada_price' === $current_filter_name ) {
|
||||
$product = wc_get_product();
|
||||
}
|
||||
$_product_id = wcj_get_product_id_or_variation_parent_id( $product );
|
||||
$_product_type = ( WCJ_IS_WC_VERSION_BELOW_3 ? $product->product_type : $product->get_type() );
|
||||
if ( WCJ_IS_WC_VERSION_BELOW_3 && 'woocommerce_get_price_html' === $current_filter_name && ! in_array( $_product_type, apply_filters( 'wcj_price_labels_woocommerce_get_price_html_allowed_post_types', array( 'booking' ), $_product_type ) ) ) {
|
||||
return $price;
|
||||
}
|
||||
if ( ! WCJ_IS_WC_VERSION_BELOW_3 && 'woocommerce_variable_price_html' === $current_filter_name ) {
|
||||
return $price;
|
||||
}
|
||||
if ( ! WCJ_IS_WC_VERSION_BELOW_3 && 'woocommerce_get_price_html' === $current_filter_name && $product->is_type( 'variation' ) ) {
|
||||
$current_filter_name = 'woocommerce_variation_price_html';
|
||||
}
|
||||
if ( ! WCJ_IS_WC_VERSION_BELOW_3 && 'woocommerce_get_price_html' === $current_filter_name && $product->is_type( 'variable' ) ) {
|
||||
$current_filter_name = 'woocommerce_variable_price_html';
|
||||
}
|
||||
if ( 'subscription' === $_product_type && 'woocommerce_subscriptions_product_price_string' !== $current_filter_name ) {
|
||||
return $price;
|
||||
}
|
||||
if ( 'variable-subscription' === $_product_type && 'woocommerce_variable_subscription_price_html' !== $current_filter_name ) {
|
||||
return $price;
|
||||
}
|
||||
if ( 'subscription_variation' === $_product_type && 'woocommerce_subscriptions_product_price_string' !== $current_filter_name ) {
|
||||
return $price;
|
||||
}
|
||||
if ( 'subscription_variation' === $_product_type && 'woocommerce_subscriptions_product_price_string' === $current_filter_name ) {
|
||||
$current_filter_name = 'woocommerce_variation_subscription_price_html';
|
||||
}
|
||||
|
||||
// Global
|
||||
$do_apply_global = true;
|
||||
$products_incl = get_option( 'wcj_global_price_labels_products_incl', array() );
|
||||
if ( ! empty( $products_incl ) ) {
|
||||
$do_apply_global = ( in_array( $_product_id, $products_incl ) ) ? true : false;
|
||||
}
|
||||
$products_excl = get_option( 'wcj_global_price_labels_products_excl', array() );
|
||||
if ( ! empty( $products_excl ) ) {
|
||||
$do_apply_global = ( in_array( $_product_id, $products_excl ) ) ? false : true;
|
||||
}
|
||||
$product_categories = get_the_terms( $_product_id, 'product_cat' );
|
||||
$product_categories_incl = get_option( 'wcj_global_price_labels_product_cats_incl', array() );
|
||||
if ( ! empty( $product_categories_incl ) ) {
|
||||
$do_apply_global = false;
|
||||
if ( ! empty( $product_categories ) ) {
|
||||
foreach ( $product_categories as $product_category ) {
|
||||
if ( in_array( $product_category->term_id, $product_categories_incl ) ) {
|
||||
$do_apply_global = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$product_categories_excl = get_option( 'wcj_global_price_labels_product_cats_excl', array() );
|
||||
if ( ! empty( $product_categories_excl ) ) {
|
||||
$do_apply_global = true;
|
||||
if ( ! empty( $product_categories ) ) {
|
||||
foreach ( $product_categories as $product_category ) {
|
||||
if ( in_array( $product_category->term_id, $product_categories_excl ) ) {
|
||||
$do_apply_global = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $do_apply_global ) {
|
||||
// Check product type
|
||||
$product_types_incl = get_option( 'wcj_global_price_labels_product_types_incl', '' );
|
||||
if ( ! empty( $product_types_incl ) ) {
|
||||
$do_apply_global = false;
|
||||
foreach ( $product_types_incl as $product_type_incl ) {
|
||||
if ( $product->is_type( $product_type_incl ) ) {
|
||||
$do_apply_global = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $do_apply_global ) {
|
||||
// Global price labels - Add text before price
|
||||
$text_to_add_before = apply_filters( 'booster_option', '', get_option( 'wcj_global_price_labels_add_before_text' ) );
|
||||
if ( '' != $text_to_add_before ) {
|
||||
if ( apply_filters( 'wcj_price_labels_check_on_applying_label', true, $price, $text_to_add_before ) ) {
|
||||
$price = $text_to_add_before . $price;
|
||||
}
|
||||
}
|
||||
// Global price labels - Add text after price
|
||||
$text_to_add_after = get_option( 'wcj_global_price_labels_add_after_text' );
|
||||
if ( '' != $text_to_add_after ) {
|
||||
if ( apply_filters( 'wcj_price_labels_check_on_applying_label', true, $price, $text_to_add_after ) ) {
|
||||
$price = $price . $text_to_add_after;
|
||||
}
|
||||
}
|
||||
// Global price labels - Between regular and sale prices
|
||||
$text_to_add_between_regular_and_sale = get_option( 'wcj_global_price_labels_between_regular_and_sale_text' );
|
||||
if ( '' != $text_to_add_between_regular_and_sale ) {
|
||||
$price = apply_filters( 'booster_option', $price, str_replace( '</del> <ins>', '</del>' . $text_to_add_between_regular_and_sale . '<ins>', $price ) );
|
||||
}
|
||||
// Global price labels - Remove text from price
|
||||
$text_to_remove = apply_filters( 'booster_option', '', get_option( 'wcj_global_price_labels_remove_text' ) );
|
||||
if ( '' != $text_to_remove ) {
|
||||
$price = str_replace( $text_to_remove, '', $price );
|
||||
}
|
||||
// Global price labels - Replace in price
|
||||
$text_to_replace = apply_filters( 'booster_option', '', get_option( 'wcj_global_price_labels_replace_text' ) );
|
||||
$text_to_replace_with = apply_filters( 'booster_option', '', get_option( 'wcj_global_price_labels_replace_with_text' ) );
|
||||
if ( '' != $text_to_replace && '' != $text_to_replace_with ) {
|
||||
$price = str_replace( $text_to_replace, $text_to_replace_with, $price );
|
||||
}
|
||||
// Global price labels - Instead of the price
|
||||
if ( '' != ( $text_instead = get_option( 'wcj_global_price_labels_instead_text', '' ) ) ) {
|
||||
$price = $text_instead;
|
||||
}
|
||||
}
|
||||
|
||||
// Per product
|
||||
if ( 'yes' === get_option( 'wcj_local_price_labels_enabled', 'yes' ) ) {
|
||||
foreach ( $this->custom_tab_sections as $custom_tab_section ) {
|
||||
$labels_array = array();
|
||||
foreach ( $this->custom_tab_section_variations as $custom_tab_section_variation ) {
|
||||
$option_name = $this->custom_tab_group_name . $custom_tab_section . $custom_tab_section_variation;
|
||||
$labels_array[ 'variation' . $custom_tab_section_variation ] = get_post_meta( $_product_id, '_' . $option_name, true );
|
||||
}
|
||||
if ( 'on' === $labels_array[ 'variation_enabled' ] ) {
|
||||
if (
|
||||
( 'on' === $labels_array['variation_home'] && is_front_page() ) ||
|
||||
( 'on' === $labels_array['variation_products'] && is_archive() ) ||
|
||||
( 'on' === $labels_array['variation_single'] && is_single() ) ||
|
||||
( 'on' === $labels_array['variation_page'] && is_page() && ! is_front_page() ) ||
|
||||
( 'on' === $labels_array['variation_cart'] && 'woocommerce_cart_item_price' === $current_filter_name ) ||
|
||||
( 'on' === $labels_array['variation_variable'] && in_array( $current_filter_name, array(
|
||||
'woocommerce_variable_empty_price_html',
|
||||
'woocommerce_variable_free_price_html',
|
||||
'woocommerce_variable_free_sale_price_html',
|
||||
'woocommerce_variable_price_html',
|
||||
'woocommerce_variable_sale_price_html',
|
||||
'woocommerce_variable_subscription_price_html',
|
||||
) ) ) ||
|
||||
( 'on' === $labels_array['variation_variation'] && in_array( $current_filter_name, array(
|
||||
'woocommerce_variation_empty_price_html',
|
||||
'woocommerce_variation_free_price_html',
|
||||
'woocommerce_variation_price_html',
|
||||
'woocommerce_variation_sale_price_html',
|
||||
'woocommerce_variation_subscription_price_html', // pseudo filter!
|
||||
) ) )
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
$price = $this->customize_price( $price, $custom_tab_section, $labels_array['variation_text'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply shortcodes
|
||||
WCJ()->shortcodes['products']->passed_product = $product;
|
||||
WCJ()->shortcodes['products_crowdfunding']->passed_product = $product;
|
||||
$result = do_shortcode( $price );
|
||||
unset( WCJ()->shortcodes['products']->passed_product );
|
||||
unset( WCJ()->shortcodes['products_crowdfunding']->passed_product );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Price_Labels();
|
||||
@@ -0,0 +1,407 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Add To Cart
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Add_To_Cart' ) ) :
|
||||
|
||||
class WCJ_Product_Add_To_Cart extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @todo (maybe) move "Display radio buttons instead of drop box for variable products" to new module
|
||||
* @todo (maybe) rename to "Add to Cart Button (Options)"
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_add_to_cart';
|
||||
$this->short_desc = __( 'Add to Cart', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set any local url to redirect to on Add to Cart.', 'woocommerce-jetpack' )
|
||||
. ' ' . __( 'Automatically add to cart on product visit.', 'woocommerce-jetpack' )
|
||||
. ' ' . __( 'Display radio buttons instead of drop box for variable products.', 'woocommerce-jetpack' )
|
||||
. ' ' . __( 'Disable quantity input.', 'woocommerce-jetpack' )
|
||||
. ' ' . __( 'Open external products on add to cart in new window.', 'woocommerce-jetpack' )
|
||||
. ' ' . __( 'Replace Add to Cart button on archives with button from single product pages.', 'woocommerce-jetpack' )
|
||||
. ' ' . __( 'Customize Add to Cart messages.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-add-to-cart';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
// Metaboxes
|
||||
if (
|
||||
'yes' === get_option( 'wcj_add_to_cart_button_custom_loop_url_per_product_enabled', 'no' ) ||
|
||||
'yes' === get_option( 'wcj_add_to_cart_button_ajax_per_product_enabled', 'no' ) ||
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_add_to_cart_redirect_per_product_enabled', 'no' ) ) ||
|
||||
'per_product' === get_option( 'wcj_add_to_cart_on_visit_enabled', 'no' )
|
||||
) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
// Customize "Continue shopping" or "View cart" messages
|
||||
if (
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_product_add_to_cart_message_continue_shopping_enabled', 'no' ) ) ||
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_product_add_to_cart_message_view_cart_enabled', 'no' ) )
|
||||
) {
|
||||
add_filter( 'wc_add_to_cart_message_html', array( $this, 'change_add_to_cart_message_html' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
// Local Redirect
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_redirect_enabled', 'no' ) || 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_add_to_cart_redirect_per_product_enabled', 'no' ) ) ) {
|
||||
add_filter( 'woocommerce_add_to_cart_redirect', array( $this, 'maybe_redirect_to_url' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Add to Cart on Visit
|
||||
if ( 'no' != get_option( 'wcj_add_to_cart_on_visit_enabled', 'no' ) ) {
|
||||
add_action( 'wp', array( $this, 'add_to_cart_on_visit' ), 98 );
|
||||
}
|
||||
|
||||
// Variable Add to Cart Template
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'wcj', get_option( 'wcj_add_to_cart_variable_as_radio_enabled', 'no' ) ) ) {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_variable_add_to_cart_scripts' ) );
|
||||
add_filter( 'wc_get_template', array( $this, 'change_variable_add_to_cart_template' ), PHP_INT_MAX, 5 );
|
||||
}
|
||||
|
||||
// Replace Add to Cart Loop with Single
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_replace_loop_w_single_enabled', 'no' ) ) {
|
||||
add_action( 'init', array( $this, 'add_to_cart_replace_loop_w_single' ), PHP_INT_MAX );
|
||||
} elseif ( 'variable_only' === get_option( 'wcj_add_to_cart_replace_loop_w_single_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_loop_add_to_cart_link', array( $this, 'add_to_cart_variable_replace_loop_w_single' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Quantity
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_quantity_disable', 'no' ) || 'yes' === get_option( 'wcj_add_to_cart_quantity_disable_cart', 'no' ) ) {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_disable_quantity_add_to_cart_script' ) );
|
||||
}
|
||||
// Quantity - Sold individually
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_quantity_sold_individually_all', 'no' ) ) {
|
||||
add_filter( 'woocommerce_is_sold_individually', '__return_true', PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Button per product Custom URL
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_button_custom_loop_url_per_product_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_product_add_to_cart_url', array( $this, 'custom_add_to_cart_loop_url' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
// Button per product AJAX
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_button_ajax_per_product_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_product_supports', array( $this, 'manage_add_to_cart_ajax' ), PHP_INT_MAX, 3 );
|
||||
}
|
||||
|
||||
// External Products
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_button_external_open_new_window_single', 'no' ) ) {
|
||||
add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'replace_external_with_custom_add_to_cart_on_single_start' ), PHP_INT_MAX );
|
||||
add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'replace_external_with_custom_add_to_cart_on_single_end' ), PHP_INT_MAX );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_button_external_open_new_window_loop', 'no' ) ) {
|
||||
add_filter( 'woocommerce_loop_add_to_cart_link', array( $this, 'replace_external_with_custom_add_to_cart_in_loop' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Reposition Add to Cart button
|
||||
if ( 'yes' === get_option( 'wcj_product_add_to_cart_button_position_enabled', 'no' ) ) {
|
||||
// Single product pages
|
||||
if ( 'yes' === get_option( 'wcj_product_add_to_cart_button_position_single_enabled', 'no' ) ) {
|
||||
add_action( 'init', array( $this, 'reposition_add_to_cart_button_single' ), PHP_INT_MAX );
|
||||
}
|
||||
// Archives
|
||||
if ( 'yes' === get_option( 'wcj_product_add_to_cart_button_position_loop_enabled', 'no' ) ) {
|
||||
add_action( 'init', array( $this, 'reposition_add_to_cart_button_loop' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reposition_add_to_cart_button_loop.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
* @todo (maybe) add option to duplicate the button (i.e. not replace)
|
||||
*/
|
||||
function reposition_add_to_cart_button_loop() {
|
||||
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
|
||||
add_action(
|
||||
get_option( 'wcj_product_add_to_cart_button_position_hook_loop', 'woocommerce_after_shop_loop_item' ),
|
||||
'woocommerce_template_loop_add_to_cart',
|
||||
get_option( 'wcj_product_add_to_cart_button_position_loop', 10 )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* reposition_add_to_cart_button_single.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
* @todo (maybe) add option to duplicate the button (i.e. not replace)
|
||||
*/
|
||||
function reposition_add_to_cart_button_single() {
|
||||
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
|
||||
add_action(
|
||||
get_option( 'wcj_product_add_to_cart_button_position_hook_single', 'woocommerce_single_product_summary' ),
|
||||
'woocommerce_template_single_add_to_cart',
|
||||
get_option( 'wcj_product_add_to_cart_button_position_single', 30 )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* change_add_to_cart_message_html.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
* @see `wc_add_to_cart_message()` in `wc-cart-functions.php`
|
||||
* @todo (maybe) product specific messages: foreach ( $products as $product_id => $qty ) ...
|
||||
* @todo (maybe) if ( WCJ_IS_WC_VERSION_BELOW_3 ) apply_filters( 'wc_add_to_cart_message' ) with 2 params: $message, $product_id
|
||||
*/
|
||||
function change_add_to_cart_message_html( $message, $products ) {
|
||||
|
||||
if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) && 'no' === apply_filters( 'booster_option', 'no', get_option( 'wcj_product_add_to_cart_message_continue_shopping_enabled', 'no' ) ) ) {
|
||||
return $message;
|
||||
}
|
||||
if ( 'yes' !== get_option( 'woocommerce_cart_redirect_after_add' ) && 'no' === apply_filters( 'booster_option', 'no', get_option( 'wcj_product_add_to_cart_message_view_cart_enabled', 'no' ) ) ) {
|
||||
return $message;
|
||||
}
|
||||
|
||||
$titles = array();
|
||||
$count = 0;
|
||||
|
||||
foreach ( $products as $product_id => $qty ) {
|
||||
$titles[] = ( $qty > 1 ? absint( $qty ) . ' × ' : '' ) . sprintf( _x( '“%s”', 'Item name in quotes', 'woocommerce' ), strip_tags( get_the_title( $product_id ) ) );
|
||||
$count += $qty;
|
||||
}
|
||||
|
||||
$titles = array_filter( $titles );
|
||||
$added_text = sprintf( _n( '%s has been added to your cart.', '%s have been added to your cart.', $count, 'woocommerce' ), wc_format_list_of_items( $titles ) );
|
||||
|
||||
if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
|
||||
$return_to = apply_filters( 'woocommerce_continue_shopping_redirect', wc_get_raw_referer() ? wp_validate_redirect( wc_get_raw_referer(), false ) : wc_get_page_permalink( 'shop' ) );
|
||||
$message = sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', esc_url( $return_to ), esc_html( get_option( 'wcj_product_add_to_cart_message_continue_shopping_text', __( 'Continue shopping', 'woocommerce' ) ) ), esc_html( $added_text ) );
|
||||
} else {
|
||||
$message = sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', esc_url( wc_get_page_permalink( 'cart' ) ), esc_html( get_option( 'wcj_product_add_to_cart_message_view_cart_text', __( 'View cart', 'woocommerce' ) ) ), esc_html( $added_text ) );
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_variable_replace_loop_w_single.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function add_to_cart_variable_replace_loop_w_single( $link ) {
|
||||
global $product;
|
||||
if ( $product->is_type( 'variable' ) ) {
|
||||
do_action( 'woocommerce_variable_add_to_cart' );
|
||||
return '';
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_replace_loop_w_single.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function add_to_cart_replace_loop_w_single() {
|
||||
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
|
||||
add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_single_add_to_cart', 30 );
|
||||
}
|
||||
|
||||
/**
|
||||
* replace_external_with_custom_add_to_cart_on_single_start.
|
||||
*
|
||||
* @version 2.5.3
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function replace_external_with_custom_add_to_cart_on_single_start() {
|
||||
global $product;
|
||||
if ( $product->is_type( 'external' ) ) {
|
||||
ob_start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* replace_external_with_custom_add_to_cart_on_single_end.
|
||||
*
|
||||
* @version 2.5.3
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function replace_external_with_custom_add_to_cart_on_single_end() {
|
||||
global $product;
|
||||
if ( $product->is_type( 'external' ) ) {
|
||||
$button_html = ob_get_contents();
|
||||
ob_end_clean();
|
||||
echo str_replace( '<a href=', '<a target="_blank" href=', $button_html );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* replace_external_with_custom_add_to_cart_in_loop.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function replace_external_with_custom_add_to_cart_in_loop( $link_html ) {
|
||||
global $product;
|
||||
if ( $product->is_type( 'external' ) ) {
|
||||
if ( false !== strpos( $link_html, '<a rel=' ) ) {
|
||||
$link_html = str_replace( '<a rel=', '<a target="_blank" rel=', $link_html );
|
||||
} else {
|
||||
$link_html = str_replace( '<a href=', '<a target="_blank" href=', $link_html );
|
||||
}
|
||||
}
|
||||
return $link_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* manage_add_to_cart_ajax.
|
||||
*
|
||||
* @version 2.5.6
|
||||
* @since 2.5.6
|
||||
*/
|
||||
function manage_add_to_cart_ajax( $supports, $feature, $_product ) {
|
||||
if ( 'ajax_add_to_cart' === $feature && 0 != get_the_ID() && 'as_shop_default' != ( $value = get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_ajax_disable', true ) ) ) {
|
||||
return ( 'yes' === $value ) ? false : true;
|
||||
}
|
||||
return $supports;
|
||||
}
|
||||
|
||||
/**
|
||||
* custom_add_to_cart_loop_url.
|
||||
*
|
||||
* @version 2.5.6
|
||||
* @since 2.5.6
|
||||
*/
|
||||
function custom_add_to_cart_loop_url( $url, $_product ) {
|
||||
if ( 0 != get_the_ID() && '' != ( $custom_url = get_post_meta( get_the_ID(), '_' . 'wcj_add_to_cart_button_loop_custom_url', true ) ) ) {
|
||||
return $custom_url;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_disable_quantity_add_to_cart_script.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
* @todo add "hide" (not just disable) option
|
||||
*/
|
||||
function enqueue_disable_quantity_add_to_cart_script() {
|
||||
if (
|
||||
( 'yes' === get_option( 'wcj_add_to_cart_quantity_disable', 'no' ) && is_product() ) ||
|
||||
( 'yes' === get_option( 'wcj_add_to_cart_quantity_disable_cart', 'no' ) && is_cart() )
|
||||
) {
|
||||
wp_enqueue_script( 'wcj-disable-quantity', wcj_plugin_url() . '/includes/js/wcj-disable-quantity.js', array( 'jquery' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_variable_add_to_cart_scripts.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function enqueue_variable_add_to_cart_scripts() {
|
||||
wp_enqueue_script( 'wcj-variations', wcj_plugin_url() . '/includes/js/wcj-variations-frontend.js', array( 'jquery' ), WCJ()->version, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_variable_add_to_cart_template.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function change_variable_add_to_cart_template( $located, $template_name, $args, $template_path, $default_path ) {
|
||||
if ( 'single-product/add-to-cart/variable.php' == $template_name ) {
|
||||
$located = untrailingslashit( realpath( plugin_dir_path( __FILE__ ) . '/..' ) ) . '/includes/templates/wcj-add-to-cart-variable.php';
|
||||
}
|
||||
return $located;
|
||||
}
|
||||
|
||||
/*
|
||||
* maybe_redirect_to_url.
|
||||
*
|
||||
* @version 3.4.0
|
||||
*/
|
||||
function maybe_redirect_to_url( $url, $product_id = false ) {
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_add_to_cart_redirect_per_product_enabled', 'no' ) ) && ( $product_id || isset( $_REQUEST['add-to-cart'] ) ) ) {
|
||||
if ( ! $product_id ) {
|
||||
$product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_REQUEST['add-to-cart'] ) );
|
||||
}
|
||||
if ( 'yes' === get_post_meta( $product_id, '_' . 'wcj_add_to_cart_redirect_enabled', true ) ) {
|
||||
$redirect_url = get_post_meta( $product_id, '_' . 'wcj_add_to_cart_redirect_url', true );
|
||||
if ( '' === $redirect_url ) {
|
||||
$redirect_url = wc_get_checkout_url();
|
||||
}
|
||||
return $redirect_url;
|
||||
}
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_add_to_cart_redirect_enabled', 'no' ) ) {
|
||||
$redirect_url = get_option( 'wcj_add_to_cart_redirect_url', '' );
|
||||
if ( '' === $redirect_url ) {
|
||||
$redirect_url = wc_get_checkout_url();
|
||||
}
|
||||
return $redirect_url;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add item to cart on visit.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @todo (maybe) optionally add product every time page is visited (instead of only once)
|
||||
*/
|
||||
function add_to_cart_on_visit() {
|
||||
if ( ! is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) && is_product() && ( $product_id = get_the_ID() ) ) {
|
||||
// If "per product" is selected - check product's settings (i.e. meta)
|
||||
if ( 'per_product' === get_option( 'wcj_add_to_cart_on_visit_enabled', 'no' ) ) {
|
||||
if ( 'yes' !== get_post_meta( $product_id, '_' . 'wcj_add_to_cart_on_visit_enabled', true ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( isset( WC()->cart ) ) {
|
||||
// Check if product already in cart
|
||||
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
$_product = $values['data'];
|
||||
if ( wcj_get_product_id_or_variation_parent_id( $_product ) == $product_id ) {
|
||||
// Product found - do not add it
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Product not found - add it
|
||||
$was_added_to_cart = WC()->cart->add_to_cart( $product_id );
|
||||
} else {
|
||||
// No products in cart - add it
|
||||
$was_added_to_cart = WC()->cart->add_to_cart( $product_id );
|
||||
}
|
||||
// Maybe perform add to cart redirect
|
||||
if ( false !== $was_added_to_cart && (
|
||||
'yes' === get_option( 'wcj_add_to_cart_redirect_enabled', 'no' ) ||
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_add_to_cart_redirect_per_product_enabled', 'no' ) )
|
||||
) ) {
|
||||
if ( $redirect_url = $this->maybe_redirect_to_url( false, $product_id ) ) {
|
||||
if ( wp_safe_redirect( $redirect_url ) ) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Add_To_Cart();
|
||||
@@ -0,0 +1,643 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Addons
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.3
|
||||
* @author Algoritmika Ltd.
|
||||
* @todo admin order view (names);
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Addons' ) ) :
|
||||
|
||||
class WCJ_Product_Addons extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.3
|
||||
* @todo (maybe) add "in progress" ajax message
|
||||
* @todo (maybe) for variable products - show addons only if variation is selected (e.g. move to addons from `woocommerce_before_add_to_cart_button` to variation description)
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_addons';
|
||||
$this->short_desc = __( 'Product Addons', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add (paid/free/discount) addons to products.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-addons';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( 'yes' === get_option( 'wcj_product_addons_per_product_enabled', 'no' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_value' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
||||
$this->co = 'wcj_product_addons_per_product_settings_enabled';
|
||||
}
|
||||
if ( wcj_is_frontend() ) {
|
||||
if ( 'yes' === get_option( 'wcj_product_addons_ajax_enabled', 'no' ) ) {
|
||||
// Scripts
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'wp_ajax_product_addons_price_change', array( $this, 'price_change_ajax' ) );
|
||||
add_action( 'wp_ajax_nopriv_product_addons_price_change', array( $this, 'price_change_ajax' ) );
|
||||
}
|
||||
// Single Page
|
||||
$position = get_option( 'wcj_product_addons_position', 'woocommerce_before_add_to_cart_button' );
|
||||
$priority = get_option( 'wcj_product_addons_position_priority', 0 );
|
||||
add_action( $position, array( $this, 'add_addons_to_frontend' ), ( 0 == $priority ? PHP_INT_MAX : $priority ) );
|
||||
// Add to cart
|
||||
add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_addons_price_to_cart_item_data' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_add_cart_item', array( $this, 'add_addons_price_to_cart_item' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_addons_price_from_session' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_on_add_to_cart' ), PHP_INT_MAX, 2 );
|
||||
// Prices
|
||||
add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'change_price' ), PHP_INT_MAX - 100, 2 );
|
||||
add_filter( 'woocommerce_product_variation_get_price', array( $this, 'change_price' ), PHP_INT_MAX - 100, 2 );
|
||||
// Show details at cart, order details, emails
|
||||
add_filter( 'woocommerce_cart_item_name', array( $this, 'add_info_to_cart_item_name' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_order_item_name', array( $this, 'add_info_to_order_item_name' ), PHP_INT_MAX, 2 );
|
||||
if ( WCJ_IS_WC_VERSION_BELOW_3 ) {
|
||||
add_action( 'woocommerce_add_order_item_meta', array( $this, 'add_info_to_order_item_meta' ), PHP_INT_MAX, 3 );
|
||||
} else {
|
||||
add_action( 'woocommerce_new_order_item', array( $this, 'add_info_to_order_item_meta_wc3' ), PHP_INT_MAX, 3 );
|
||||
}
|
||||
}
|
||||
if ( is_admin() ) {
|
||||
if ( 'yes' === get_option( 'wcj_product_addons_hide_on_admin_order_page', 'no' ) ) {
|
||||
add_filter( 'woocommerce_hidden_order_itemmeta', array( $this, 'hide_addons_in_admin_order' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
// Addons quantity
|
||||
$qty_triggers = get_option( 'wcj_product_addons_qty_decrease_triggers', '' );
|
||||
if ( ! empty( $qty_triggers ) ) {
|
||||
if ( in_array( 'woocommerce_new_order', $qty_triggers ) ) {
|
||||
$qty_triggers = array_merge( $qty_triggers, array(
|
||||
'woocommerce_api_create_order',
|
||||
'woocommerce_cli_create_order',
|
||||
'kco_before_confirm_order',
|
||||
'woocommerce_checkout_order_processed',
|
||||
) );
|
||||
}
|
||||
foreach ( $qty_triggers as $qty_trigger ) {
|
||||
add_action( $qty_trigger, array( $this, 'maybe_reduce_addons_qty' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_reduce_addons_qty.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 3.3.0
|
||||
* @todo (maybe) $order->add_order_note
|
||||
*/
|
||||
function maybe_reduce_addons_qty( $order_id ) {
|
||||
if ( $order = wc_get_order( $order_id ) ) {
|
||||
if ( 'yes' !== get_post_meta( $order_id, '_' . 'wcj_product_addons_qty_reduced', true ) ) {
|
||||
if ( sizeof( $order->get_items() ) > 0 ) {
|
||||
foreach ( $order->get_items() as $item ) {
|
||||
if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) ) {
|
||||
$product_id = wcj_get_product_id_or_variation_parent_id( $product );
|
||||
$product_qty = $item->get_quantity();
|
||||
$global_addon_key = '_wcj_product_all_products_addons_label_';
|
||||
$global_addon_key_length = strlen( $global_addon_key );
|
||||
$local_addon_key = '_wcj_product_per_product_addons_label_';
|
||||
$local_addon_key_length = strlen( $local_addon_key );
|
||||
foreach ( $item->get_meta_data() as $meta_data ) {
|
||||
$meta = $meta_data->get_data();
|
||||
if ( $global_addon_key === substr( $meta['key'], 0, $global_addon_key_length ) ) {
|
||||
$i = substr( $meta['key'], $global_addon_key_length );
|
||||
$qty_key = 'wcj_product_addons_all_products_qty_' . $i;
|
||||
$old_qty = get_option( $qty_key, '' );
|
||||
if ( '' !== $old_qty ) {
|
||||
$new_qty = $old_qty - $product_qty;
|
||||
update_option( $qty_key, $new_qty );
|
||||
}
|
||||
} elseif ( $local_addon_key === substr( $meta['key'], 0, $local_addon_key_length ) ) {
|
||||
$i = substr( $meta['key'], $local_addon_key_length );
|
||||
$qty_key = '_' . 'wcj_product_addons_per_product_qty_' . $i;
|
||||
$old_qty = get_post_meta( $product_id, $qty_key, true );
|
||||
if ( '' !== $old_qty ) {
|
||||
$new_qty = $old_qty - $product_qty;
|
||||
update_post_meta( $product_id, $qty_key, $new_qty );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
update_post_meta( $order_id, '_' . 'wcj_product_addons_qty_reduced', 'yes' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_addons_in_admin_order.
|
||||
*
|
||||
* @version 2.5.6
|
||||
* @since 2.5.6
|
||||
* @todo get real number of addons (instead of max_addons = 100)
|
||||
*/
|
||||
function hide_addons_in_admin_order( $hidden_metas ) {
|
||||
$max_addons = 100;
|
||||
for ( $i = 1; $i <= $max_addons; $i++ ) {
|
||||
$hidden_metas[] = '_' . 'wcj_product_all_products_addons_price_' . $i;
|
||||
$hidden_metas[] = '_' . 'wcj_product_all_products_addons_label_' . $i;
|
||||
$hidden_metas[] = '_' . 'wcj_product_per_product_addons_price_' . $i;
|
||||
$hidden_metas[] = '_' . 'wcj_product_per_product_addons_label_' . $i;
|
||||
}
|
||||
return $hidden_metas;
|
||||
}
|
||||
|
||||
/**
|
||||
* validate_on_add_to_cart.
|
||||
*
|
||||
* @version 2.5.5
|
||||
* @since 2.5.5
|
||||
*/
|
||||
function validate_on_add_to_cart( $passed, $product_id ) {
|
||||
$addons = $this->get_product_addons( $product_id );
|
||||
foreach ( $addons as $addon ) {
|
||||
if ( 'yes' === $addon['is_required'] ) {
|
||||
if ( ! isset( $_POST[ $addon['checkbox_key'] ] ) ) {
|
||||
wc_add_notice( __( 'Some of the required addons are not selected!', 'woocommerce-jetpack' ), 'error' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $passed;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_the_notice.
|
||||
*
|
||||
* @version 2.5.3
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function get_the_notice() {
|
||||
return __( 'Booster: Free plugin\'s version is limited to only three products with per product addons enabled at a time. You will need to get <a href="https://booster.io/plus/" target="_blank">Booster Plus</a> to add unlimited number of products with per product addons.', 'woocommerce-jetpack' );
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_convert_currency.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function maybe_convert_currency( $price, $product = null ) {
|
||||
$apply_price_filters = get_option( 'wcj_product_addons_apply_price_filters', 'by_module' );
|
||||
if ( 'by_module' === $apply_price_filters ) {
|
||||
// Multicurrency Product Base Price module
|
||||
if ( WCJ()->modules['multicurrency_base_price']->is_enabled() ) {
|
||||
$price = WCJ()->modules['multicurrency_base_price']->change_price( $price, $product );
|
||||
}
|
||||
// Multicurrency (Currency Switcher) module
|
||||
if ( WCJ()->modules['multicurrency']->is_enabled() ) {
|
||||
$price = WCJ()->modules['multicurrency']->change_price( $price, null );
|
||||
}
|
||||
} elseif ( 'yes' === $apply_price_filters ) {
|
||||
$price = apply_filters( WCJ_PRODUCT_GET_PRICE_FILTER, $price, $product );
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* clean_and_explode.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 3.7.0
|
||||
* @todo move this to global functions (`wcj_clean_and_explode()`)
|
||||
*/
|
||||
function clean_and_explode( $delimiter, $string ) {
|
||||
return array_map( 'trim', explode( $delimiter, trim( $string ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* price_change_ajax.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function price_change_ajax( $param ) {
|
||||
if ( ! isset( $_POST['product_id'] ) || 0 == $_POST['product_id'] ) {
|
||||
die();
|
||||
}
|
||||
$the_product = wc_get_product( $_POST['product_id'] );
|
||||
$parent_product_id = ( $the_product->is_type( 'variation' ) ) ? wp_get_post_parent_id( $_POST['product_id'] ) : $_POST['product_id'];
|
||||
$addons = $this->get_product_addons( $parent_product_id );
|
||||
$the_addons_price = 0;
|
||||
foreach ( $addons as $addon ) {
|
||||
if ( isset( $_POST[ $addon['checkbox_key'] ] ) ) {
|
||||
if ( ( 'checkbox' === $addon['type'] || '' == $addon['type'] ) || ( 'text' == $addon['type'] && '' != $_POST[ $addon['checkbox_key'] ] ) ) {
|
||||
$the_addons_price += $addon['price_value'];
|
||||
} elseif ( 'radio' === $addon['type'] || 'select' === $addon['type'] ) {
|
||||
$labels = $this->clean_and_explode( PHP_EOL, $addon['label_value'] );
|
||||
$prices = $this->clean_and_explode( PHP_EOL, $addon['price_value'] );
|
||||
if ( count( $labels ) === count( $prices ) ) {
|
||||
foreach ( $labels as $i => $label ) {
|
||||
if ( $_POST[ $addon['checkbox_key'] ] == sanitize_title( $label ) ) {
|
||||
$the_addons_price += $prices[ $i ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( 0 != $the_addons_price ) {
|
||||
$the_price = $the_product->get_price();
|
||||
$the_display_price = wcj_get_product_display_price( $the_product, ( $the_price + $this->maybe_convert_currency( $the_addons_price, $the_product ) ) );
|
||||
echo wc_price( $the_display_price );
|
||||
} else {
|
||||
echo $the_product->get_price_html();
|
||||
}
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_scripts.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function enqueue_scripts() {
|
||||
if ( is_product() ) {
|
||||
$the_product = wc_get_product();
|
||||
$addons = $this->get_product_addons( wcj_get_product_id_or_variation_parent_id( $the_product ) );
|
||||
if ( ! empty( $addons ) ) {
|
||||
$is_variable_with_single_price = ( $the_product->is_type( 'variable' ) && ( $the_product->get_variation_price( 'min' ) == $the_product->get_variation_price( 'max' ) ) );
|
||||
wp_enqueue_script( 'wcj-product-addons', wcj_plugin_url() . '/includes/js/wcj-product-addons.js', array(), WCJ()->version, true );
|
||||
wp_localize_script( 'wcj-product-addons', 'ajax_object', array(
|
||||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||
'product_id' => get_the_ID(),
|
||||
'is_variable_with_single_price' => $is_variable_with_single_price,
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* is_global_addon_visible.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 3.0.0
|
||||
* @todo add "include only products"
|
||||
* @todo add "include/exclude categories/tags"
|
||||
*/
|
||||
function is_global_addon_visible( $i, $product_id ) {
|
||||
$exclude_products = get_option( 'wcj_product_addons_all_products_exclude_products_' . $i, '' );
|
||||
if ( ! empty( $exclude_products ) && in_array( $product_id, $exclude_products ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_product_addons.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.3
|
||||
* @todo (maybe) `checkbox_key` is mislabelled, should be `key` (or maybe `value_key`)
|
||||
*/
|
||||
function get_product_addons( $product_id ) {
|
||||
$addons = array();
|
||||
// All Products
|
||||
if ( 'yes' === get_option( 'wcj_product_addons_all_products_enabled', 'no' ) ) {
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_product_addons_all_products_total_number', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( 'yes' === get_option( 'wcj_product_addons_all_products_enabled_' . $i, 'yes' ) ) {
|
||||
if ( ! $this->is_global_addon_visible( $i, $product_id ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( '0' === ( $qty = get_option( 'wcj_product_addons_all_products_qty_' . $i, '' ) ) || $qty < 0 ) {
|
||||
continue;
|
||||
}
|
||||
$addons[] = array(
|
||||
// 'scope' => 'all_products',
|
||||
// 'index' => $i,
|
||||
'checkbox_key' => 'wcj_product_all_products_addons_' . $i,
|
||||
'price_key' => 'wcj_product_all_products_addons_price_' . $i,
|
||||
'label_key' => 'wcj_product_all_products_addons_label_' . $i,
|
||||
'price_value' => get_option( 'wcj_product_addons_all_products_price_' . $i ),
|
||||
'label_value' => do_shortcode( get_option( 'wcj_product_addons_all_products_label_' . $i ) ),
|
||||
'title' => do_shortcode( get_option( 'wcj_product_addons_all_products_title_' . $i, '' ) ),
|
||||
'placeholder' => do_shortcode( get_option( 'wcj_product_addons_all_products_placeholder_' . $i, '' ) ),
|
||||
'class' => get_option( 'wcj_product_addons_all_products_class_' . $i, '' ),
|
||||
'tooltip' => do_shortcode( get_option( 'wcj_product_addons_all_products_tooltip_' . $i, '' ) ),
|
||||
'type' => get_option( 'wcj_product_addons_all_products_type_' . $i, 'checkbox' ),
|
||||
'default' => get_option( 'wcj_product_addons_all_products_default_' . $i, '' ),
|
||||
'is_required' => get_option( 'wcj_product_addons_all_products_required_' . $i, 'no' ),
|
||||
'qty' => $qty,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Per product
|
||||
if ( 'yes' === get_option( 'wcj_product_addons_per_product_enabled', 'no' ) ) {
|
||||
if ( 'yes' === get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_settings_enabled', true ) ) {
|
||||
$total_number = get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_total_number', true );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
if ( 'yes' === get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_enabled_' . $i, true ) ) {
|
||||
if ( '0' === ( $qty = get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_qty_' . $i, true ) ) || $qty < 0 ) {
|
||||
continue;
|
||||
}
|
||||
$addons[] = array(
|
||||
// 'scope' => 'per_product',
|
||||
// 'index' => $i,
|
||||
'checkbox_key' => 'wcj_product_per_product_addons_' . $i,
|
||||
'price_key' => 'wcj_product_per_product_addons_price_' . $i,
|
||||
'label_key' => 'wcj_product_per_product_addons_label_' . $i,
|
||||
'price_value' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_price_' . $i, true ),
|
||||
'label_value' => do_shortcode( get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_label_' . $i, true ) ),
|
||||
'title' => do_shortcode( get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_title_' . $i, true ) ),
|
||||
'placeholder' => do_shortcode( get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_placeholder_' . $i, true ) ),
|
||||
'class' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_class_' . $i, true ),
|
||||
'tooltip' => do_shortcode( get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_tooltip_' . $i, true ) ),
|
||||
'type' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_type_' . $i, true ),
|
||||
'default' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_default_' . $i, true ),
|
||||
'is_required' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_required_' . $i, true ),
|
||||
'qty' => $qty,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $addons;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_info_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_info_to_order_item_meta_wc3( $item_id, $item, $order_id ) {
|
||||
if ( is_a( $item, 'WC_Order_Item_Product' ) ) {
|
||||
$this->add_info_to_order_item_meta( $item_id, $item->legacy_values, null );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_info_to_order_item_meta.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function add_info_to_order_item_meta( $item_id, $values, $cart_item_key ) {
|
||||
$addons = $this->get_product_addons( $values['product_id'] );
|
||||
$product = wc_get_product( $values['product_id'] );
|
||||
foreach ( $addons as $addon ) {
|
||||
if ( isset( $values[ $addon['price_key'] ] ) ) {
|
||||
wc_add_order_item_meta( $item_id, '_' . $addon['price_key'], $this->maybe_convert_currency( $values[ $addon['price_key'] ], $product ) );
|
||||
wc_add_order_item_meta( $item_id, '_' . $addon['label_key'], $values[ $addon['label_key'] ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds info to order details (and emails).
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function add_info_to_order_item_name( $name, $item, $is_cart = false ) {
|
||||
if ( $is_cart ) {
|
||||
$start_format = get_option( 'wcj_product_addons_cart_format_start', '<dl class="variation">' );
|
||||
$item_format = get_option( 'wcj_product_addons_cart_format_each_addon', '<dt>%addon_label%:</dt><dd>%addon_price%</dd>' );
|
||||
$end_format = get_option( 'wcj_product_addons_cart_format_end', '</dl>' );
|
||||
} else {
|
||||
$start_format = get_option( 'wcj_product_addons_order_details_format_start', '' );
|
||||
$item_format = get_option( 'wcj_product_addons_order_details_format_each_addon', ' | %addon_label%: %addon_price%' );
|
||||
$end_format = get_option( 'wcj_product_addons_order_details_format_end', '' );
|
||||
}
|
||||
$name .= $start_format;
|
||||
$addons = $this->get_product_addons( $item['product_id'] );
|
||||
$_product = wc_get_product( $item['product_id'] );
|
||||
foreach ( $addons as $addon ) {
|
||||
if ( isset( $item[ $addon['price_key'] ] ) ) {
|
||||
$addon_price = ( $is_cart ) ? $this->maybe_convert_currency( $item[ $addon['price_key'] ], $_product ) : $item[ $addon['price_key'] ];
|
||||
$name .= str_replace(
|
||||
array( '%addon_label%', '%addon_price%' ),
|
||||
array( $item[ $addon['label_key'] ], wc_price( wcj_get_product_display_price( $_product, $addon_price ) ) ),
|
||||
$item_format
|
||||
);
|
||||
}
|
||||
}
|
||||
$name .= $end_format;
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds info to cart item details.
|
||||
*
|
||||
* @version 2.5.3
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function add_info_to_cart_item_name( $name, $cart_item, $cart_item_key ) {
|
||||
return $this->add_info_to_order_item_name( $name, $cart_item, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function change_price( $price, $_product ) {
|
||||
$addons = $this->get_product_addons( wcj_get_product_id_or_variation_parent_id( $_product ) );
|
||||
foreach ( $addons as $addon ) {
|
||||
if ( isset( $_product->{$addon['price_key']} ) ) {
|
||||
$price += $_product->{$addon['price_key']};
|
||||
}
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_addons_price_to_cart_item.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function add_addons_price_to_cart_item( $cart_item_data, $cart_item_key ) {
|
||||
$addons = $this->get_product_addons( ( WCJ_IS_WC_VERSION_BELOW_3 ? $cart_item_data['data']->product_id : wcj_get_product_id_or_variation_parent_id( $cart_item_data['data'] ) ) );
|
||||
foreach ( $addons as $addon ) {
|
||||
if ( isset( $cart_item_data[ $addon['price_key'] ] ) ) {
|
||||
$cart_item_data['data']->{$addon['price_key']} = $cart_item_data[ $addon['price_key'] ];
|
||||
}
|
||||
}
|
||||
return $cart_item_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_cart_item_addons_price_from_session.
|
||||
*
|
||||
* @version 2.5.6
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function get_cart_item_addons_price_from_session( $item, $values, $addon ) {
|
||||
$addons = $this->get_product_addons( $item['product_id'] );
|
||||
foreach ( $addons as $addon ) {
|
||||
if ( array_key_exists( $addon['price_key'], $values ) ) {
|
||||
$item['data']->{$addon['price_key']} = $values[ $addon['price_key'] ];
|
||||
}
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_addons_price_to_cart_item_data.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function add_addons_price_to_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
|
||||
$addons = $this->get_product_addons( $product_id );
|
||||
foreach ( $addons as $addon ) {
|
||||
if ( isset( $_POST[ $addon['checkbox_key'] ] ) ) {
|
||||
if ( ( 'checkbox' === $addon['type'] || '' == $addon['type'] ) || ( 'text' == $addon['type'] && '' != $_POST[ $addon['checkbox_key'] ] ) ) {
|
||||
$cart_item_data[ $addon['price_key'] ] = $addon['price_value'];
|
||||
$cart_item_data[ $addon['label_key'] ] = $addon['label_value'];
|
||||
if ( 'text' == $addon['type'] ) {
|
||||
$cart_item_data[ $addon['label_key'] ] .= ' (' . $_POST[ $addon['checkbox_key'] ] . ')';
|
||||
}
|
||||
} elseif ( 'radio' === $addon['type'] || 'select' === $addon['type'] ) {
|
||||
$prices = $this->clean_and_explode( PHP_EOL, $addon['price_value'] );
|
||||
$labels = $this->clean_and_explode( PHP_EOL, $addon['label_value'] );
|
||||
if ( count( $labels ) === count( $prices ) ) {
|
||||
foreach ( $labels as $i => $label ) {
|
||||
if ( $_POST[ $addon['checkbox_key'] ] == sanitize_title( $label ) ) {
|
||||
$cart_item_data[ $addon['price_key'] ] = $prices[ $i ];
|
||||
$cart_item_data[ $addon['label_key'] ] = $labels[ $i ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $cart_item_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_addons_to_frontend.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function add_addons_to_frontend() {
|
||||
if ( isset( $this->are_addons_displayed ) ) {
|
||||
return;
|
||||
}
|
||||
$html = '';
|
||||
$addons = $this->get_product_addons( get_the_ID() );
|
||||
$_product = wc_get_product( get_the_ID() );
|
||||
foreach ( $addons as $addon ) {
|
||||
if ( '' != $addon['title'] ) {
|
||||
$html .= wcj_handle_replacements( array(
|
||||
'%addon_id%' => $addon['checkbox_key'],
|
||||
'%addon_title%' => $addon['title'],
|
||||
), get_option( 'wcj_product_addons_template_title', '<p><label for="%addon_id%">%addon_title%</label></p>' ) );
|
||||
}
|
||||
$is_required = ( 'yes' === $addon['is_required'] ) ? ' required' : '';
|
||||
if ( 'checkbox' === $addon['type'] || '' == $addon['type'] ) {
|
||||
$is_checked = '';
|
||||
if ( isset( $_POST[ $addon['checkbox_key'] ] ) ) {
|
||||
$is_checked = ' checked';
|
||||
} elseif ( 'checked' === $addon['default'] ) {
|
||||
$is_checked = ' checked';
|
||||
}
|
||||
$maybe_tooltip = ( '' != $addon['tooltip'] ) ?
|
||||
' <img style="display:inline;" class="wcj-question-icon" src="' . wcj_plugin_url() . '/assets/images/question-icon.png' . '" title="' . $addon['tooltip'] . '">' :
|
||||
'';
|
||||
$html .= wcj_handle_replacements( array(
|
||||
'%addon_input%' => '<input type="checkbox" id="' . $addon['checkbox_key'] . '" class="' . $addon['class'] . '" name="' . $addon['checkbox_key'] . '"' . $is_checked . $is_required . '>',
|
||||
'%addon_id%' => $addon['checkbox_key'],
|
||||
'%addon_label%' => $addon['label_value'],
|
||||
'%addon_price%' => wc_price( wcj_get_product_display_price( $_product, $this->maybe_convert_currency( $addon['price_value'], $_product ) ) ),
|
||||
'%addon_tooltip%' => $maybe_tooltip,
|
||||
), get_option( 'wcj_product_addons_template_type_checkbox',
|
||||
'<p>%addon_input% <label for="%addon_id%">%addon_label% (%addon_price%)</label>%addon_tooltip%</p>' ) );
|
||||
} elseif ( 'text' == $addon['type'] ) {
|
||||
$default_value = ( isset( $_POST[ $addon['checkbox_key'] ] ) ? $_POST[ $addon['checkbox_key'] ] : $addon['default'] );
|
||||
$maybe_tooltip = ( '' != $addon['tooltip'] ) ?
|
||||
' <img style="display:inline;" class="wcj-question-icon" src="' . wcj_plugin_url() . '/assets/images/question-icon.png' . '" title="' . $addon['tooltip'] . '">' :
|
||||
'';
|
||||
$html .= wcj_handle_replacements( array(
|
||||
'%addon_input%' => '<input type="text" id="' . $addon['checkbox_key'] . '" class="' . $addon['class'] . '" name="' . $addon['checkbox_key'] . '" placeholder="' . $addon['placeholder'] . '" value="' . $default_value . '"' . $is_required . '>',
|
||||
'%addon_id%' => $addon['checkbox_key'],
|
||||
'%addon_label%' => $addon['label_value'],
|
||||
'%addon_price%' => wc_price( wcj_get_product_display_price( $_product, $this->maybe_convert_currency( $addon['price_value'], $_product ) ) ),
|
||||
'%addon_tooltip%' => $maybe_tooltip,
|
||||
), get_option( 'wcj_product_addons_template_type_text',
|
||||
'<p><label for="%addon_id%">%addon_label% (%addon_price%)</label> %addon_input%%addon_tooltip%</p>' ) );
|
||||
} elseif ( 'radio' === $addon['type'] || 'select' === $addon['type'] ) {
|
||||
$prices = $this->clean_and_explode( PHP_EOL, $addon['price_value'] );
|
||||
$labels = $this->clean_and_explode( PHP_EOL, $addon['label_value'] );
|
||||
if ( 'radio' === $addon['type'] ) {
|
||||
$tooltips = $this->clean_and_explode( PHP_EOL, $addon['tooltip'] );
|
||||
}
|
||||
if ( count( $labels ) === count( $prices ) ) {
|
||||
if ( 'select' === $addon['type'] ) {
|
||||
$select_options = '';
|
||||
}
|
||||
foreach ( $labels as $i => $label ) {
|
||||
$label = sanitize_title( $label );
|
||||
$is_checked = '';
|
||||
$checked_or_selected = ( 'radio' === $addon['type'] ? ' checked' : ' selected' );
|
||||
if ( isset( $_POST[ $addon['checkbox_key'] ] ) ) {
|
||||
$is_checked = ( $label === $_POST[ $addon['checkbox_key'] ] ) ? $checked_or_selected : '';
|
||||
} elseif ( '' != $addon['default'] ) {
|
||||
$is_checked = ( $label === sanitize_title( $addon['default'] ) ) ? $checked_or_selected : '';
|
||||
}
|
||||
if ( 'radio' === $addon['type'] ) {
|
||||
$maybe_tooltip = ( isset( $tooltips[ $i ] ) && '' != $tooltips[ $i ] ) ?
|
||||
' <img style="display:inline;" class="wcj-question-icon" src="' . wcj_plugin_url() . '/assets/images/question-icon.png' . '" title="' . $tooltips[ $i ] . '">' :
|
||||
'';
|
||||
$html .= wcj_handle_replacements( array(
|
||||
'%addon_input%' => '<input type="radio" id="' . $addon['checkbox_key'] . '-' . $label . '" class="' . $addon['class'] . '" name="' . $addon['checkbox_key'] . '" value="' . $label . '"' . $is_checked . $is_required . '>',
|
||||
'%addon_id%' => $addon['checkbox_key'] . '-' . $label,
|
||||
'%addon_label%' => $labels[ $i ],
|
||||
'%addon_price%' => wc_price( wcj_get_product_display_price( $_product, $this->maybe_convert_currency( $prices[ $i ], $_product ) ) ),
|
||||
'%addon_tooltip%' => $maybe_tooltip,
|
||||
), get_option( 'wcj_product_addons_template_type_radio',
|
||||
'<p>%addon_input% <label for="%addon_id%">%addon_label% (%addon_price%)</label>%addon_tooltip%</p>' ) );
|
||||
} else {
|
||||
$select_options .= '<option value="' . $label . '"' . $is_checked . '>' . $labels[ $i ] . ' ('. wc_price( wcj_get_product_display_price( $_product, $this->maybe_convert_currency( $prices[ $i ], $_product ) ) ) . ')' . '</option>';
|
||||
}
|
||||
}
|
||||
if ( 'select' === $addon['type'] ) {
|
||||
$maybe_tooltip = ( '' != $addon['tooltip'] ) ?
|
||||
' <img style="display:inline;" class="wcj-question-icon" src="' . wcj_plugin_url() . '/assets/images/question-icon.png' . '" title="' . $addon['tooltip'] . '">' :
|
||||
'';
|
||||
if ( '' != $addon['placeholder'] ) {
|
||||
$select_options = '<option value="">' . $addon['placeholder'] . '</option>' . $select_options;
|
||||
}
|
||||
$html .= wcj_handle_replacements( array(
|
||||
'%addon_input%' => '<select' . $is_required . ' id="' . $addon['checkbox_key'] . '" class="' . $addon['class'] . '" name="' . $addon['checkbox_key'] . '">' . $select_options . '</select>',
|
||||
'%addon_tooltip%' => $maybe_tooltip,
|
||||
), get_option( 'wcj_product_addons_template_type_select', '<p>%addon_input%%addon_tooltip%</p>' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Output
|
||||
if ( ! empty( $html ) ) {
|
||||
echo wcj_handle_replacements( array(
|
||||
'%addons_html%' => $html,
|
||||
), get_option( 'wcj_product_addons_template_final', '<div id="wcj_product_addons">%addons_html%</div>' ) );
|
||||
$this->are_addons_displayed = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Addons();
|
||||
@@ -0,0 +1,436 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Bookings
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Bookings' ) ) :
|
||||
|
||||
class WCJ_Product_Bookings extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_bookings';
|
||||
$this->short_desc = __( 'Bookings', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add bookings products to WooCommerce.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-bookings';
|
||||
$this->extra_desc = __( 'When enabled, module will add new "Booster: Bookings" meta box to each product\'s edit page.', 'woocommerce-jetpack' );
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
|
||||
if ( wcj_is_frontend() ) {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'wp_ajax_price_change', array( $this, 'price_change_ajax' ) );
|
||||
add_action( 'wp_ajax_nopriv_price_change', array( $this, 'price_change_ajax' ) );
|
||||
// Prices
|
||||
add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'change_price' ), PHP_INT_MAX - 100, 2 );
|
||||
add_filter( 'woocommerce_product_variation_get_price', array( $this, 'change_price' ), PHP_INT_MAX - 100, 2 );
|
||||
// Single Page
|
||||
add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'add_input_fields_to_frontend' ), PHP_INT_MAX );
|
||||
// Add to cart
|
||||
add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_bookings_on_add_to_cart' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_bookings_price_to_cart_item_data' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_add_cart_item', array( $this, 'add_bookings_price_to_cart_item' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_bookings_price_from_session' ), PHP_INT_MAX, 3 );
|
||||
// Price html
|
||||
add_filter( 'woocommerce_get_price_html', array( $this, 'add_per_day_label' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_get_variation_price_html', array( $this, 'add_per_day_label' ), PHP_INT_MAX, 2 );
|
||||
// Add to Cart button on archives
|
||||
add_filter( 'woocommerce_product_add_to_cart_url', array( $this, 'add_to_cart_url' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'add_to_cart_text' ), PHP_INT_MAX, 2 );
|
||||
// Show details at cart, order details, emails
|
||||
add_filter( 'woocommerce_cart_item_name', array( $this, 'add_info_to_cart_item_name' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_order_item_name', array( $this, 'add_info_to_order_item_name' ), PHP_INT_MAX, 2 );
|
||||
if ( WCJ_IS_WC_VERSION_BELOW_3 ) {
|
||||
add_action( 'woocommerce_add_order_item_meta', array( $this, 'add_info_to_order_item_meta' ), PHP_INT_MAX, 3 );
|
||||
} else {
|
||||
add_action( 'woocommerce_checkout_create_order_line_item', array( $this, 'add_info_to_order_item_meta_wc3' ), PHP_INT_MAX, 4 );
|
||||
}
|
||||
// Hide quantity
|
||||
if ( 'yes' === get_option( 'wcj_product_bookings_hide_quantity', 'yes' ) ) {
|
||||
add_filter( 'woocommerce_is_sold_individually', array( $this, 'sold_individually' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
// Disable AJAX add to cart
|
||||
add_filter( 'woocommerce_product_supports', array( $this, 'disable_add_to_cart_ajax' ), PHP_INT_MAX, 3 );
|
||||
}
|
||||
|
||||
add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_value' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* disable_add_to_cart_ajax.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function disable_add_to_cart_ajax( $supports, $feature, $_product ) {
|
||||
if ( $this->is_bookings_product( $_product ) && 'ajax_add_to_cart' === $feature ) {
|
||||
$supports = false;
|
||||
}
|
||||
return $supports;
|
||||
}
|
||||
|
||||
/**
|
||||
* sold_individually.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function sold_individually( $return, $_product ) {
|
||||
return ( $this->is_bookings_product( $_product ) ) ? true : $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* price_change_ajax.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function price_change_ajax( $param ) {
|
||||
if ( isset( $_POST['date_from'] ) && '' != $_POST['date_from'] && isset( $_POST['date_to'] ) && '' != $_POST['date_to'] && isset( $_POST['product_id'] ) && '' != $_POST['product_id'] ) {
|
||||
$date_to = strtotime( $_POST['date_to'] );
|
||||
$date_from = strtotime( $_POST['date_from'] );
|
||||
$seconds_diff = $date_to - $date_from;
|
||||
$days_diff = ( $seconds_diff / 60 / 60 / 24 );
|
||||
$the_product = wc_get_product( $_POST['product_id'] );
|
||||
$price_per_day = wcj_get_product_display_price( $the_product );
|
||||
$the_price = $days_diff * $price_per_day;
|
||||
echo wc_price( $the_price );
|
||||
}
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_scripts.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.5.0
|
||||
* @todo add "calculating price" progress message
|
||||
*/
|
||||
function enqueue_scripts() {
|
||||
if ( is_product() ) {
|
||||
$the_product = wc_get_product();
|
||||
if ( $this->is_bookings_product( $the_product ) ) {
|
||||
wp_enqueue_script( 'wcj-bookings', wcj_plugin_url() . '/includes/js/wcj-bookings.js', array(), WCJ()->version, true );
|
||||
wp_localize_script( 'wcj-bookings', 'ajax_object', array(
|
||||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||
'product_id' => get_the_ID(),
|
||||
'wrong_dates_message' => get_option( 'wcj_product_bookings_message_date_to_before_date_from', __( '"Date to" must be after "Date from"', 'woocommerce-jetpack' ) ),
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_text.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_to_cart_text( $text, $_product ) {
|
||||
return ( $this->is_bookings_product( $_product ) ) ? __( 'Read more', 'woocommerce' ) : $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_url.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_to_cart_url( $url, $_product ) {
|
||||
return ( $this->is_bookings_product( $_product ) ) ? get_permalink( wcj_get_product_id_or_variation_parent_id( $_product ) ) : $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_info_to_order_item_meta_wc3.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
*/
|
||||
function add_info_to_order_item_meta_wc3( $item, $cart_item_key, $values, $order ) {
|
||||
$meta_keys = array( 'wcj_bookings_price', 'wcj_bookings_date_from', 'wcj_bookings_date_to' );
|
||||
foreach ( $meta_keys as $meta_key ) {
|
||||
if ( isset( $values[ $meta_key ] ) ) {
|
||||
$item[ '_' . $meta_key ] = $values[ $meta_key ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_info_to_order_item_meta.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_info_to_order_item_meta( $item_id, $values, $cart_item_key ) {
|
||||
if ( isset( $values['wcj_bookings_price'] ) ) {
|
||||
wc_add_order_item_meta( $item_id, '_' . 'wcj_bookings_price', $values['wcj_bookings_price'] );
|
||||
wc_add_order_item_meta( $item_id, '_' . 'wcj_bookings_date_from', $values['wcj_bookings_date_from'] );
|
||||
wc_add_order_item_meta( $item_id, '_' . 'wcj_bookings_date_to', $values['wcj_bookings_date_to'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds info to order details (and emails).
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_info_to_order_item_name( $name, $item, $is_cart = false ) {
|
||||
if ( $is_cart ) {
|
||||
$name .= '<dl class="variation">';
|
||||
}
|
||||
if ( isset( $item['wcj_bookings_price'] ) ) {
|
||||
if ( $is_cart ) {
|
||||
$name .= '<dt>' . get_option( 'wcj_product_bookings_label_period', __( 'Period', 'woocommerce-jetpack' ) ) . ':' . '</dt>';
|
||||
$name .= '<dd>' . $item['wcj_bookings_date_from'] . ' - ' . $item['wcj_bookings_date_to'] . '</dd>';
|
||||
} else {
|
||||
$name .= ' | ' . $item['wcj_bookings_date_from'] . ' - ' . $item['wcj_bookings_date_to'];
|
||||
}
|
||||
}
|
||||
if ( $is_cart ) {
|
||||
$name .= '</dl>';
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds info to cart item details.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_info_to_cart_item_name( $name, $cart_item, $cart_item_key ) {
|
||||
return $this->add_info_to_order_item_name( $name, $cart_item, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* validate_bookings_on_add_to_cart.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function validate_bookings_on_add_to_cart( $passed, $product_id ) {
|
||||
$the_product = wc_get_product( $product_id );
|
||||
if ( $this->is_bookings_product( $the_product ) ) {
|
||||
if ( ! isset( $_POST['wcj_product_bookings_date_from'] ) || '' == $_POST['wcj_product_bookings_date_from'] ) {
|
||||
wc_add_notice( get_option( 'wcj_product_bookings_message_no_date_from', __( '"Date from" must be set', 'woocommerce-jetpack' ) ), 'error' );
|
||||
return false;
|
||||
}
|
||||
if ( ! isset( $_POST['wcj_product_bookings_date_to'] ) || '' == $_POST['wcj_product_bookings_date_to'] ) {
|
||||
wc_add_notice( get_option( 'wcj_product_bookings_message_no_date_to', __( '"Date to" must be set', 'woocommerce-jetpack' ) ), 'error' );
|
||||
return false;
|
||||
}
|
||||
$date_to = strtotime( $_POST['wcj_product_bookings_date_to'] );
|
||||
$date_from = strtotime( $_POST['wcj_product_bookings_date_from'] );
|
||||
if ( $date_from >= $date_to ) {
|
||||
wc_add_notice( get_option( 'wcj_product_bookings_message_date_to_before_date_from', __( '"Date to" must be after "Date from"', 'woocommerce-jetpack' ) ), 'error' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $passed;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_cart_item_bookings_price_from_session.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function get_cart_item_bookings_price_from_session( $item, $values, $key ) {
|
||||
if ( array_key_exists( 'wcj_bookings_price', $values ) ) {
|
||||
$item['data']->wcj_bookings_price = $values['wcj_bookings_price'];
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_bookings_price_to_cart_item_data.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_bookings_price_to_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
|
||||
if ( isset( $_POST['wcj_product_bookings_date_to'] ) && isset( $_POST['wcj_product_bookings_date_from'] ) ) {
|
||||
$the_product = wc_get_product( $product_id );
|
||||
if ( $this->is_bookings_product( $the_product ) ) {
|
||||
$date_to = strtotime( $_POST['wcj_product_bookings_date_to'] );
|
||||
$date_from = strtotime( $_POST['wcj_product_bookings_date_from'] );
|
||||
$seconds_diff = $date_to - $date_from;
|
||||
$days_diff = ( $seconds_diff / 60 / 60 / 24 );
|
||||
if ( 0 != $variation_id ) {
|
||||
$the_product = wc_get_product( $variation_id );
|
||||
}
|
||||
$price_per_day = $the_product->get_price();
|
||||
$the_price = $days_diff * $price_per_day;
|
||||
$cart_item_data['wcj_bookings_price'] = $the_price;
|
||||
$cart_item_data['wcj_bookings_date_from'] = $_POST['wcj_product_bookings_date_from'];
|
||||
$cart_item_data['wcj_bookings_date_to'] = $_POST['wcj_product_bookings_date_to'];
|
||||
// wc_add_notice( sprintf( __( 'Price for %d days: %s', 'woocommerce-jetpack' ), $days_diff, wc_price( $the_price ) ), 'notice' );
|
||||
}
|
||||
}
|
||||
return $cart_item_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_bookings_price_to_cart_item.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_bookings_price_to_cart_item( $cart_item_data, $cart_item_key ) {
|
||||
if ( isset( $cart_item_data['wcj_bookings_price'] ) ) {
|
||||
$cart_item_data['data']->wcj_bookings_price = $cart_item_data['wcj_bookings_price'];
|
||||
}
|
||||
return $cart_item_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_input_fields_to_frontend.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.5.0
|
||||
* @todo more options: exclude days (1-31), exact availability dates, mindate, maxdate, firstday, dateformat etc.
|
||||
*/
|
||||
function add_input_fields_to_frontend() {
|
||||
if ( isset( $this->are_bookings_input_fields_displayed ) ) {
|
||||
return;
|
||||
}
|
||||
if ( $this->is_bookings_product( wc_get_product() ) ) {
|
||||
$data_table = array();
|
||||
$date_from_value = ( isset( $_POST['wcj_product_bookings_date_from'] ) ) ? $_POST['wcj_product_bookings_date_from'] : '';
|
||||
$date_to_value = ( isset( $_POST['wcj_product_bookings_date_to'] ) ) ? $_POST['wcj_product_bookings_date_to'] : '';
|
||||
$date_from_exclude_days = ( '' != ( $exclude = get_option( 'wcj_product_bookings_datepicker_date_from_exclude_days', '' ) ) ?
|
||||
' excludedays="[' . str_replace( 'S', '0', implode( ',', $exclude ) ) . ']"' : '' );
|
||||
$date_to_exclude_days = ( '' != ( $exclude = get_option( 'wcj_product_bookings_datepicker_date_to_exclude_days', '' ) ) ?
|
||||
' excludedays="[' . str_replace( 'S', '0', implode( ',', $exclude ) ) . ']"' : '' );
|
||||
$date_from_exclude_months = ( '' != ( $exclude = get_option( 'wcj_product_bookings_datepicker_date_from_exclude_months', '' ) ) ?
|
||||
' excludemonths="[' . implode( ',', $exclude ) . ']"' : '' );
|
||||
$date_to_exclude_months = ( '' != ( $exclude = get_option( 'wcj_product_bookings_datepicker_date_to_exclude_months', '' ) ) ?
|
||||
' excludemonths="[' . implode( ',', $exclude ) . ']"' : '' );
|
||||
$data_table[] = array(
|
||||
'<label for="wcj_product_bookings_date_from">' . get_option( 'wcj_product_bookings_label_date_from', __( 'Date from' ) ) . '</label>',
|
||||
'<input firstday="0"' . $date_from_exclude_days . $date_from_exclude_months . ' dateformat="mm/dd/yy" mindate="0" type="datepicker" display="date" id="wcj_product_bookings_date_from" name="wcj_product_bookings_date_from" placeholder="" value="' . $date_from_value . '">',
|
||||
);
|
||||
$data_table[] = array(
|
||||
'<label for="wcj_product_bookings_date_to">' . get_option( 'wcj_product_bookings_label_date_to', __( 'Date to' ) ) . '</label>',
|
||||
'<input firstday="0"' . $date_to_exclude_days . $date_to_exclude_months . ' dateformat="mm/dd/yy" mindate="0" type="datepicker" display="date" id="wcj_product_bookings_date_to" name="wcj_product_bookings_date_to" placeholder="" value="' . $date_to_value . '">',
|
||||
);
|
||||
echo wcj_get_table_html( $data_table, array( 'table_heading_type' => 'none', ) );
|
||||
echo '<div style="display:none !important;" name="wcj_bookings_message"><p style="color:red;"></p></div>';
|
||||
$this->are_bookings_input_fields_displayed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_per_day_label.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_per_day_label( $price_html, $_product ) {
|
||||
return ( $this->is_bookings_product( $_product ) ) ? $price_html . ' ' . get_option( 'wcj_product_bookings_label_per_day', __( '/ day', 'woocommerce-jetpack' ) ) : $price_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function change_price( $price, $_product ) {
|
||||
return ( $this->is_bookings_product( $_product ) && isset( $_product->wcj_bookings_price ) ) ? $_product->wcj_bookings_price : $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* save_meta_box_value.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function save_meta_box_value( $option_value, $option_name, $module_id ) {
|
||||
if ( true === apply_filters( 'booster_option', false, true ) ) {
|
||||
return $option_value;
|
||||
}
|
||||
if ( 'no' === $option_value ) {
|
||||
return $option_value;
|
||||
}
|
||||
if ( $this->id === $module_id && 'wcj_product_bookings_enabled' === $option_name ) {
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => 1,
|
||||
'meta_key' => '_' . 'wcj_product_bookings_enabled',
|
||||
'meta_value' => 'yes',
|
||||
'post__not_in' => array( get_the_ID() ),
|
||||
);
|
||||
$loop = new WP_Query( $args );
|
||||
$c = $loop->found_posts + 1;
|
||||
if ( $c >= 2 ) {
|
||||
add_filter( 'redirect_post_location', array( $this, 'add_notice_query_var' ), 99 );
|
||||
return 'no';
|
||||
}
|
||||
}
|
||||
return $option_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_notice_query_var.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_notice_query_var( $location ) {
|
||||
remove_filter( 'redirect_post_location', array( $this, 'add_notice_query_var' ), 99 );
|
||||
return add_query_arg( array( 'wcj_product_bookings_admin_notice' => true ), $location );
|
||||
}
|
||||
|
||||
/**
|
||||
* admin_notices.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function admin_notices() {
|
||||
if ( ! isset( $_GET['wcj_product_bookings_admin_notice'] ) ) {
|
||||
return;
|
||||
}
|
||||
?><div class="error"><p><?php
|
||||
echo '<div class="message">'
|
||||
. __( 'Booster: Free plugin\'s version is limited to only one bookings product enabled at a time. You will need to get <a href="https://booster.io/plus/" target="_blank">Booster Plus</a> to add unlimited number of bookings products.', 'woocommerce-jetpack' )
|
||||
. '</div>';
|
||||
?></p></div><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* is_bookings_product.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function is_bookings_product( $_product ) {
|
||||
return ( 'yes' === get_post_meta( wcj_get_product_id_or_variation_parent_id( $_product ), '_' . 'wcj_product_bookings_enabled', true ) ) ? true : false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Bookings();
|
||||
@@ -0,0 +1,429 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Bulk Meta Editor
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 2.8.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Bulk_Meta_Editor' ) ) :
|
||||
|
||||
class WCJ_Product_Bulk_Meta_Editor extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_bulk_meta_editor';
|
||||
$this->short_desc = __( 'Product Bulk Meta Editor', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set products meta with bulk editor.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-bulk-meta-editor';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'product_bulk_meta_editor' => array(
|
||||
'title' => __( 'Product Bulk Meta Editor', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Product Bulk Meta Editor Tool.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* create_product_bulk_meta_editor_tool.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
* @todo (maybe) real permalink instead of `/?p=`
|
||||
* @todo (maybe) `wc_add_notice`
|
||||
* @todo (maybe) tab order (go through input fields in meta table)
|
||||
* @todo (maybe) "save" on enter key ("wrong form" issue)
|
||||
* @todo (maybe) all "submit" inputs as single "name" but with different "value"
|
||||
* @todo (maybe) products by category; tag; custom taxonomy
|
||||
* @todo (maybe) "delete all meta" button (for single product) - needs confirmation
|
||||
* @todo (maybe) checkboxes for each product
|
||||
* @todo (maybe) sortable columns in meta table
|
||||
* @todo (maybe) multiple meta keys
|
||||
*/
|
||||
function create_product_bulk_meta_editor_tool() {
|
||||
// Actions
|
||||
$result = $this->perform_actions();
|
||||
// Preparing products data
|
||||
$_products = wcj_get_products( array(), 'any', 512, ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_product_bulk_meta_editor_add_variations', 'no' ) ) ) );
|
||||
$selected_products = isset( $_POST['wcj_product_bulk_meta_editor_products'] ) ? $_POST['wcj_product_bulk_meta_editor_products'] : array();
|
||||
// Output
|
||||
echo $this->get_tool_html( $result['meta_name'], $result['result_message'], $_products, $selected_products, $result['set_meta'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* perform_actions.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
* @todo break this into separate functions
|
||||
*/
|
||||
function perform_actions() {
|
||||
$meta_name = '';
|
||||
$set_meta = '';
|
||||
$result_message = '';
|
||||
if (
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_save_single'] ) && 0 != $_POST['wcj_product_bulk_meta_editor_save_single'] &&
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_meta'] ) && '' !== $_POST['wcj_product_bulk_meta_editor_meta']
|
||||
) {
|
||||
$meta_name = $_POST['wcj_product_bulk_meta_editor_meta'];
|
||||
$success = 0;
|
||||
$fail = 0;
|
||||
$_product_id = $_POST['wcj_product_bulk_meta_editor_save_single'];
|
||||
if ( update_post_meta( $_product_id, $meta_name, $_POST[ 'wcj_product_bulk_meta_editor_id_' . $_product_id ] ) ) {
|
||||
$success++;
|
||||
} else {
|
||||
$fail++;
|
||||
}
|
||||
$result_message = $this->get_result_message( $success, $fail );
|
||||
} elseif (
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_delete_single'] ) && 0 != $_POST['wcj_product_bulk_meta_editor_delete_single'] &&
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_meta'] ) && '' !== $_POST['wcj_product_bulk_meta_editor_meta']
|
||||
) {
|
||||
$meta_name = $_POST['wcj_product_bulk_meta_editor_meta'];
|
||||
$success = 0;
|
||||
$fail = 0;
|
||||
$_product_id = $_POST['wcj_product_bulk_meta_editor_delete_single'];
|
||||
if ( delete_post_meta( $_product_id, $meta_name ) ) {
|
||||
$success++;
|
||||
} else {
|
||||
$fail++;
|
||||
}
|
||||
$result_message = $this->get_result_message( $success, $fail );
|
||||
} elseif (
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_save_all'] ) &&
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_meta'] ) && '' !== $_POST['wcj_product_bulk_meta_editor_meta']
|
||||
) {
|
||||
$meta_name = $_POST['wcj_product_bulk_meta_editor_meta'];
|
||||
$key_start_length = strlen( 'wcj_product_bulk_meta_editor_id_' );
|
||||
$success = 0;
|
||||
$fail = 0;
|
||||
foreach ( $_POST as $key => $value ) {
|
||||
if ( false !== strpos( $key, 'wcj_product_bulk_meta_editor_id_' ) ) {
|
||||
$product_id = substr( $key, $key_start_length - strlen( $key ) );
|
||||
if ( update_post_meta( $product_id, $meta_name, $value ) ) {
|
||||
$success++;
|
||||
} else {
|
||||
$fail++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$result_message = $this->get_result_message( $success, $fail );
|
||||
} elseif (
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_delete_all'] ) &&
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_meta'] ) && '' !== $_POST['wcj_product_bulk_meta_editor_meta']
|
||||
) {
|
||||
$meta_name = $_POST['wcj_product_bulk_meta_editor_meta'];
|
||||
$key_start_length = strlen( 'wcj_product_bulk_meta_editor_id_' );
|
||||
$success = 0;
|
||||
$fail = 0;
|
||||
foreach ( $_POST as $key => $value ) {
|
||||
if ( false !== strpos( $key, 'wcj_product_bulk_meta_editor_id_' ) ) {
|
||||
$product_id = substr( $key, $key_start_length - strlen( $key ) );
|
||||
if ( delete_post_meta( $product_id, $meta_name ) ) {
|
||||
$success++;
|
||||
} else {
|
||||
$fail++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$result_message = $this->get_result_message( $success, $fail );
|
||||
} elseif (
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_set'] ) &&
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_set_meta'] ) &&
|
||||
isset( $_POST['wcj_product_bulk_meta_editor_meta'] ) && '' !== $_POST['wcj_product_bulk_meta_editor_meta']
|
||||
) {
|
||||
$meta_name = $_POST['wcj_product_bulk_meta_editor_meta'];
|
||||
$set_meta = $_POST['wcj_product_bulk_meta_editor_set_meta'];
|
||||
$key_start_length = strlen( 'wcj_product_bulk_meta_editor_id_' );
|
||||
$success = 0;
|
||||
$fail = 0;
|
||||
foreach ( $_POST as $key => $value ) {
|
||||
if ( false !== strpos( $key, 'wcj_product_bulk_meta_editor_id_' ) ) {
|
||||
$product_id = substr( $key, $key_start_length - strlen( $key ) );
|
||||
if ( update_post_meta( $product_id, $meta_name, $set_meta ) ) {
|
||||
$success++;
|
||||
} else {
|
||||
$fail++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$result_message = $this->get_result_message( $success, $fail );
|
||||
} elseif ( isset( $_POST['wcj_product_bulk_meta_editor_show'] ) ) {
|
||||
if ( '' === $_POST['wcj_product_bulk_meta_editor_show_meta'] ) {
|
||||
$result_message = '<p><div class="error"><p>' . __( 'Please enter meta key.', 'woocommerce-jetpack' ) . '</p></div></p>';
|
||||
}
|
||||
$meta_name = $_POST['wcj_product_bulk_meta_editor_show_meta'];
|
||||
}
|
||||
return array(
|
||||
'meta_name' => $meta_name,
|
||||
'set_meta' => $set_meta,
|
||||
'result_message' => $result_message,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* get_result_message.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function get_result_message( $success, $fail ) {
|
||||
$result_message = '';
|
||||
if ( $success > 0 ) {
|
||||
$result_message .= '<p><div class="notice notice-success is-dismissible"><p>' . sprintf( __( 'Meta for <strong>%d</strong> product(s) was updated.', 'woocommerce-jetpack' ), $success ) . '</p></div></p>';
|
||||
}
|
||||
if ( $fail > 0 ) {
|
||||
$result_message .= '<p><div class="notice notice-warning is-dismissible"><p>' . sprintf( __( 'Meta for <strong>%d</strong> product(s) was not updated.', 'woocommerce-jetpack' ), $fail ) . '</p></div></p>';
|
||||
}
|
||||
return $result_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_tool_html.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function get_tool_html( $meta_name, $result_message, $_products, $selected_products, $set_meta ) {
|
||||
$html = '';
|
||||
$html .= '<div class="wrap">';
|
||||
$html .= $this->get_tool_header_html( 'product_bulk_meta_editor' );
|
||||
$html .= $result_message;
|
||||
$html .= '<form method="post" action="">';
|
||||
$html .= $this->get_html_meta_key_input( $meta_name );
|
||||
$html .= $this->get_html_products_select( $_products, $selected_products );
|
||||
if ( '' != $meta_name ) {
|
||||
$html .= $this->get_html_meta_table( $meta_name, $_products, $selected_products, $set_meta );
|
||||
}
|
||||
$html .= '</form>';
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_html_meta_key_input.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function get_html_meta_key_input( $meta_name ) {
|
||||
$meta_html = '';
|
||||
$meta_html .= '<p>';
|
||||
$meta_html .= '<label for="wcj_product_bulk_meta_editor_show_meta">';
|
||||
$meta_html .= __( 'Meta key', 'woocommerce-jetpack' );
|
||||
if ( '' == $meta_name ) {
|
||||
$meta_html .= ', ' . sprintf( __( 'for example %s', 'woocommerce-jetpack' ), '<code>_sku</code>' );
|
||||
}
|
||||
$meta_html .= '</label>';
|
||||
$meta_html .= '<input required class="widefat" type="text" id="wcj_product_bulk_meta_editor_show_meta" name="wcj_product_bulk_meta_editor_show_meta" value="' . $meta_name . '">';
|
||||
$meta_html .= '</p>';
|
||||
$meta_html .= '<p>';
|
||||
$meta_html .= '<button class="button-primary" type="submit" name="wcj_product_bulk_meta_editor_show" value="show">' . __( 'Show', 'woocommerce-jetpack' ) . '</button>';
|
||||
$meta_html .= '</p>';
|
||||
$table_data = array();
|
||||
$table_data[] = array(
|
||||
__( 'Meta', 'woocommerce-jetpack' ),
|
||||
);
|
||||
$table_data[] = array(
|
||||
$meta_html,
|
||||
);
|
||||
return '<p>' . wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) ) . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* get_html_products_select.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function get_html_products_select( $_products, $selected_products ) {
|
||||
$products_html = '';
|
||||
$products_html .= '<select name="wcj_product_bulk_meta_editor_products[]" multiple style="height:300px;width:100%;">';
|
||||
foreach ( $_products as $product_id => $product_title ) {
|
||||
$selected = ( empty( $selected_products ) || in_array( $product_id, $selected_products ) ? ' selected' : '' );
|
||||
$products_html .= '<option' . $selected . ' value="' . $product_id . '">' . $product_title . '</option>';
|
||||
}
|
||||
$products_html .= '</select>';
|
||||
$tip = '<p style="font-style:italic;color:gray;">' . '* ' .
|
||||
__( 'Hold <strong>Control</strong> key to select multiple products. Press <strong>Control</strong> + <strong>A</strong> to select all products.', 'woocommerce-jetpack' ) .
|
||||
'</p>';
|
||||
$table_data = array();
|
||||
$table_data[] = array(
|
||||
__( 'Products', 'woocommerce-jetpack' ),
|
||||
);
|
||||
$table_data[] = array(
|
||||
$products_html . $tip,
|
||||
);
|
||||
return '<p>' . wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) ) . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* get_html_meta_table.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function get_html_meta_table( $meta_name, $_products, $selected_products, $set_meta ) {
|
||||
$html = '';
|
||||
$js_confirmation = ' onclick="return confirm(\'' . __( 'Are you sure?', 'woocommerce-jetpack' ) . '\')"';
|
||||
$html .= $this->get_html_meta_table_set_single_value( $set_meta, $js_confirmation );
|
||||
$html .= $this->get_html_meta_table_buttons( $meta_name, $js_confirmation );
|
||||
$html .= $this->get_html_meta_table_content( $meta_name, $_products, $selected_products, $js_confirmation );
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_html_meta_table_set_single_value.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function get_html_meta_table_set_single_value( $set_meta, $js_confirmation ) {
|
||||
$single_value_html = '<p>' .
|
||||
'<label for="wcj_product_bulk_meta_editor_set_meta">' . __( 'Value', 'woocommerce-jetpack' ) . '</label>' .
|
||||
'<input type="text" class="widefat" id="wcj_product_bulk_meta_editor_set_meta" name="wcj_product_bulk_meta_editor_set_meta" value="' . $set_meta . '">' .
|
||||
'</p>' .
|
||||
'<p>' .
|
||||
'<button class="button-primary" type="submit" name="wcj_product_bulk_meta_editor_set" value="set"' . $js_confirmation . '>' .
|
||||
__( 'Set', 'woocommerce-jetpack' ) . '</button>' .
|
||||
'</p>';
|
||||
$table_data = array();
|
||||
$table_data[] = array(
|
||||
__( 'Set Meta for All Products', 'woocommerce-jetpack' ),
|
||||
);
|
||||
$table_data[] = array(
|
||||
$single_value_html,
|
||||
);
|
||||
return '<p>' . wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) ) . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* get_html_meta_table_buttons.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function get_html_meta_table_buttons( $meta_name, $js_confirmation ) {
|
||||
$html = '';
|
||||
$html .= '<p>';
|
||||
$html .= '<input class="button-primary" type="submit" name="wcj_product_bulk_meta_editor_save_all" value="' . __( 'Save all', 'woocommerce-jetpack' ) . '"' .
|
||||
$js_confirmation . '>';
|
||||
$html .= ' ';
|
||||
$html .= '<input class="button-primary" type="submit" name="wcj_product_bulk_meta_editor_delete_all" value="' . __( 'Delete all', 'woocommerce-jetpack' ) . '"' .
|
||||
$js_confirmation . '>';
|
||||
$html .= '</p>';
|
||||
$html .= '<input type="hidden" name="wcj_product_bulk_meta_editor_meta" value="' . $meta_name . '">';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_html_meta_table_content.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function get_html_meta_table_content( $meta_name, $_products, $selected_products, $js_confirmation ) {
|
||||
$table_data = array();
|
||||
$table_headings = array(
|
||||
__( 'Product', 'woocommerce-jetpack' ),
|
||||
__( 'Meta', 'woocommerce-jetpack' ) . ': <code>' . $meta_name . '</code>',
|
||||
'',
|
||||
);
|
||||
$additional_columns = get_option( 'wcj_product_bulk_meta_editor_additional_columns', '' );
|
||||
$table_headings = $this->maybe_add_additional_columns_headings( $table_headings, $additional_columns );
|
||||
$table_data[] = $table_headings;
|
||||
foreach ( $_products as $product_id => $product_title ) {
|
||||
if ( ! in_array( $product_id, $selected_products ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! metadata_exists( 'post', $product_id, $meta_name ) && 'yes' === get_option( 'wcj_product_bulk_meta_editor_check_if_exists', 'no' ) ) {
|
||||
$_post_meta = '<em>' . 'N/A' . '</em>';
|
||||
$save_button = '';
|
||||
$delete_button = '';
|
||||
} else {
|
||||
$_post_meta = get_post_meta( $product_id, $meta_name, true );
|
||||
if ( is_array( $_post_meta ) || is_object( $_post_meta ) ) {
|
||||
$_post_meta = print_r( $_post_meta, true );
|
||||
} else {
|
||||
$placeholder = ( ! metadata_exists( 'post', $product_id, $meta_name ) ? ' placeholder="N/A"' : '' );
|
||||
$_post_meta = '<input' . $placeholder . ' style="width:100%;" type="text" name="wcj_product_bulk_meta_editor_id_' . $product_id . '" value="' .
|
||||
$_post_meta . '">';
|
||||
}
|
||||
$save_button = '<button class="button-primary" type="submit" name="wcj_product_bulk_meta_editor_save_single" value="' . $product_id . '">'
|
||||
. __( 'Save', 'woocommerce-jetpack' ) . '</button>';
|
||||
$delete_button = ( metadata_exists( 'post', $product_id, $meta_name ) ?
|
||||
'<button class="button-primary" type="submit" name="wcj_product_bulk_meta_editor_delete_single" value="' . $product_id . '"' . $js_confirmation . '>'
|
||||
. __( 'Delete', 'woocommerce-jetpack' ) . '</button>' : '' );
|
||||
}
|
||||
$row = array(
|
||||
'<a href="/?p=' . $product_id . '"> ' . $product_title . '</a>',
|
||||
$_post_meta,
|
||||
$save_button . ' ' . $delete_button,
|
||||
);
|
||||
$row = $this->maybe_add_additional_columns_content( $row, $additional_columns, $product_id );
|
||||
$table_data[] = $row;
|
||||
}
|
||||
return '<p>' . wcj_get_table_html( $table_data, array( 'table_class' => 'widefat striped' ) ) . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_additional_columns_headings.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function maybe_add_additional_columns_headings( $table_headings, $additional_columns ) {
|
||||
if ( ! empty( $additional_columns ) ) {
|
||||
if ( in_array( 'product_id', $additional_columns ) ) {
|
||||
$table_headings[] = __( 'Product ID', 'woocommerce-jetpack' );
|
||||
}
|
||||
if ( in_array( 'product_status', $additional_columns ) ) {
|
||||
$table_headings[] = __( 'Product status', 'woocommerce-jetpack' );
|
||||
}
|
||||
if ( in_array( 'product_all_meta_keys', $additional_columns ) ) {
|
||||
$table_headings[] = __( 'Meta keys', 'woocommerce-jetpack' );
|
||||
}
|
||||
}
|
||||
return $table_headings;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_additional_columns_content.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function maybe_add_additional_columns_content( $row, $additional_columns, $product_id ) {
|
||||
if ( ! empty( $additional_columns ) ) {
|
||||
if ( in_array( 'product_id', $additional_columns ) ) {
|
||||
$row[] = $product_id;
|
||||
}
|
||||
if ( in_array( 'product_status', $additional_columns ) ) {
|
||||
$row[] = get_post_status( $product_id );
|
||||
}
|
||||
if ( in_array( 'product_all_meta_keys', $additional_columns ) ) {
|
||||
$row[] = '<details style="color:gray;">' .
|
||||
'<summary><em>' . __( 'Show all', 'woocommerce-jetpack' ) . '</em></summary>' .
|
||||
'<p>' . implode( '<br>', array_keys( get_post_meta( $product_id ) ) ) . '</p>' .
|
||||
'</details>';
|
||||
}
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Bulk_Meta_Editor();
|
||||
@@ -0,0 +1,325 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Bulk Price Converter
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @author Algoritmika Ltd.
|
||||
* @todo clear products transients after converting prices
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Bulk_Price_Converter' ) ) :
|
||||
|
||||
class WCJ_Bulk_Price_Converter extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'bulk_price_converter';
|
||||
$this->short_desc = __( 'Bulk Price Converter', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Multiply all products prices by set value.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-bulk-price-converter';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'bulk_price_converter' => array(
|
||||
'title' => __( 'Bulk Price Converter', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Bulk Price Converter Tool.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_by_type.
|
||||
*
|
||||
* @version 2.4.4
|
||||
*/
|
||||
function change_price_by_type( $product_id, $multiply_price_by, $price_type, $is_preview, $parent_product_id, $min_price = 0, $max_price = 0 ) {
|
||||
$the_price = get_post_meta( $product_id, '_' . $price_type, true );
|
||||
$the_modified_price = $the_price;
|
||||
if ( '' != $the_price && 0 != $the_price ) {
|
||||
$precision = get_option( 'woocommerce_price_num_decimals', 2 );
|
||||
$the_modified_price = round( $the_price * $multiply_price_by, $precision );
|
||||
if ( isset( $_POST['make_pretty_prices_threshold'] ) && apply_filters( 'booster_option', 0, $_POST['make_pretty_prices_threshold'] ) > 0 ) {
|
||||
$the_modified_price = $this->make_pretty_price( $the_modified_price );
|
||||
}
|
||||
if ( $the_modified_price < 0 ) {
|
||||
$the_modified_price = 0;
|
||||
}
|
||||
if ( 0 != $min_price && $the_modified_price < $min_price ) {
|
||||
$the_modified_price = $min_price;
|
||||
}
|
||||
if ( 0 != $max_price && $the_modified_price > $max_price ) {
|
||||
$the_modified_price = $max_price;
|
||||
}
|
||||
if ( ! $is_preview ) {
|
||||
update_post_meta( $product_id, '_' . $price_type, $the_modified_price );
|
||||
}
|
||||
}
|
||||
|
||||
$product_cats = array();
|
||||
$product_terms = get_the_terms( $parent_product_id, 'product_cat' );
|
||||
if ( is_array( $product_terms ) ) {
|
||||
foreach ( $product_terms as $term ) {
|
||||
$product_cats[] = esc_html( $term->name );
|
||||
}
|
||||
}
|
||||
if ( '' != $the_price || '' != $the_modified_price ) {
|
||||
echo '<tr>' .
|
||||
'<td>' . get_the_title( $product_id ) . '</td>' .
|
||||
'<td>' . implode( ', ', $product_cats ) . '</td>' .
|
||||
'<td>' . '<em>' . $price_type . '</em>' . '</td>' .
|
||||
'<td>' . $the_price . '</td>' .
|
||||
'<td>' . $the_modified_price . '</td>' .
|
||||
'</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_all_types.
|
||||
*
|
||||
* @version 2.4.4
|
||||
*/
|
||||
function change_price_all_types( $product_id, $multiply_price_by, $is_preview, $parent_product_id ) {
|
||||
$what_prices_to_modify = ( isset( $_POST['wcj_price_types'] ) ) ? $_POST['wcj_price_types'] : 'wcj_both';
|
||||
if ( 'wcj_both' === $what_prices_to_modify ) {
|
||||
$this->change_price_by_type( $product_id, $multiply_price_by, 'price', $is_preview, $parent_product_id );
|
||||
$this->change_price_by_type( $product_id, $multiply_price_by, 'sale_price', $is_preview, $parent_product_id );
|
||||
$this->change_price_by_type( $product_id, $multiply_price_by, 'regular_price', $is_preview, $parent_product_id );
|
||||
} elseif ( 'wcj_sale_prices' === $what_prices_to_modify ) {
|
||||
if ( get_post_meta( $product_id, '_' . 'price', true ) === get_post_meta( $product_id, '_' . 'sale_price', true ) ) {
|
||||
$this->change_price_by_type( $product_id, $multiply_price_by, 'price', $is_preview, $parent_product_id,
|
||||
0, get_post_meta( $product_id, '_' . 'regular_price', true ) );
|
||||
}
|
||||
$this->change_price_by_type( $product_id, $multiply_price_by, 'sale_price', $is_preview, $parent_product_id,
|
||||
0, get_post_meta( $product_id, '_' . 'regular_price', true ) );
|
||||
} elseif ( 'wcj_regular_prices' === $what_prices_to_modify ) {
|
||||
if ( get_post_meta( $product_id, '_' . 'price', true ) === get_post_meta( $product_id, '_' . 'regular_price', true ) ) {
|
||||
if (
|
||||
get_post_meta( $product_id, '_' . 'price', true ) !== get_post_meta( $product_id, '_' . 'sale_price', true ) ||
|
||||
$multiply_price_by <= 1
|
||||
) {
|
||||
$this->change_price_by_type( $product_id, $multiply_price_by, 'price', $is_preview, $parent_product_id,
|
||||
get_post_meta( $product_id, '_' . 'sale_price', true ), 0 );
|
||||
}
|
||||
}
|
||||
$this->change_price_by_type( $product_id, $multiply_price_by, 'regular_price', $is_preview, $parent_product_id,
|
||||
get_post_meta( $product_id, '_' . 'sale_price', true ), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_product_price.
|
||||
*
|
||||
* @version 2.4.0
|
||||
*/
|
||||
function change_product_price( $product_id, $multiply_price_by, $is_preview ) {
|
||||
$this->change_price_all_types( $product_id, $multiply_price_by, $is_preview, $product_id );
|
||||
// Handling variable products
|
||||
$product = wc_get_product( $product_id );
|
||||
if ( $product->is_type( 'variable' ) ) {
|
||||
$variations = $product->get_available_variations();
|
||||
foreach( $variations as $variation ) {
|
||||
$this->change_price_all_types( $variation['variation_id'], $multiply_price_by, $is_preview, $product_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_all_products_prices
|
||||
*
|
||||
* @version 2.4.4
|
||||
*/
|
||||
function change_all_products_prices( $multiply_prices_by, $is_preview ) {
|
||||
$multiply_prices_by = floatval( $multiply_prices_by );
|
||||
if ( $multiply_prices_by <= 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ob_start();
|
||||
|
||||
echo '<table class="widefat" style="width:50%; min-width: 300px; margin-top: 10px;">';
|
||||
echo '<tr>' .
|
||||
'<th>' . __( 'Product', 'woocommerce-jetpack' ) . '</th>' .
|
||||
'<th>' . __( 'Categories', 'woocommerce-jetpack' ) . '</th>' .
|
||||
'<th>' . __( 'Price Type', 'woocommerce-jetpack' ) . '</th>' .
|
||||
'<th>' . __( 'Original Price', 'woocommerce-jetpack' ) . '</th>' .
|
||||
'<th>' . __( 'Modified Price', 'woocommerce-jetpack' ) . '</th>' .
|
||||
'</tr>';
|
||||
|
||||
$offset = 0;
|
||||
$block_size = 96;
|
||||
while( true ) {
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => $block_size,
|
||||
'offset' => $offset,
|
||||
// 'orderby' => 'date',
|
||||
// 'order' => 'ASC',
|
||||
);
|
||||
if ( isset( $_POST['wcj_product_cat'] ) && 'wcj_any' != $_POST['wcj_product_cat'] && 'any' != apply_filters( 'booster_option', 'any', '' ) ) {
|
||||
$args['tax_query'] = array(
|
||||
array(
|
||||
'taxonomy' => 'product_cat',
|
||||
'field' => 'slug',
|
||||
'terms' => array( $_POST['wcj_product_cat'] ),
|
||||
'operator' => ( 'wcj_none' != $_POST['wcj_product_cat'] ) ? 'IN' : 'NOT EXISTS',
|
||||
),
|
||||
);
|
||||
}
|
||||
$loop = new WP_Query( $args );
|
||||
if ( ! $loop->have_posts() ) break;
|
||||
while ( $loop->have_posts() ) : $loop->the_post();
|
||||
$this->change_product_price( $loop->post->ID, $multiply_prices_by, $is_preview );
|
||||
endwhile;
|
||||
$offset += $block_size;
|
||||
}
|
||||
wp_reset_postdata();
|
||||
|
||||
echo '</table>';
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* create_bulk_price_converter_tool.
|
||||
*
|
||||
* @version 2.4.4
|
||||
*/
|
||||
function create_bulk_price_converter_tool() {
|
||||
|
||||
$result_message = '';
|
||||
|
||||
$multiply_prices_by = isset( $_POST['multiply_prices_by'] ) ? $_POST['multiply_prices_by'] : 1;
|
||||
$is_preview = isset( $_POST['bulk_change_prices_preview'] ) ? true : false;
|
||||
|
||||
$result_changing_prices = '';
|
||||
|
||||
if ( $multiply_prices_by <= 0 ) {
|
||||
$result_message = '<p><div class="error"><p><strong>' . __( 'Multiply value must be above zero.', 'woocommerce-jetpack' ) . '</strong></p></div></p>';
|
||||
$multiply_prices_by = 1;
|
||||
}
|
||||
else {
|
||||
if ( isset( $_POST['bulk_change_prices'] ) || isset( $_POST['bulk_change_prices_preview'] ) ) {
|
||||
$result_changing_prices = $this->change_all_products_prices( $multiply_prices_by, $is_preview );
|
||||
if ( ! $is_preview ) {
|
||||
$result_message = '<p><div class="updated"><p><strong>' . __( 'Prices changed successfully!', 'woocommerce-jetpack' ) .
|
||||
'</strong></p></div></p>';
|
||||
$multiply_prices_by = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$select_options_html = '';
|
||||
$selected_option = ( isset( $_POST['wcj_product_cat'] ) ) ? $_POST['wcj_product_cat'] : '';
|
||||
$product_categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
|
||||
if ( ! empty( $product_categories ) && ! is_wp_error( $product_categories ) ) {
|
||||
foreach ( $product_categories as $product_category ) {
|
||||
$select_options_html .= '<option value="' . $product_category->slug . '"' . selected( $product_category->slug, $selected_option, false ) . '>' .
|
||||
$product_category->name .
|
||||
'</option>';
|
||||
}
|
||||
}
|
||||
|
||||
// Output HTML
|
||||
echo '<div>';
|
||||
echo $this->get_tool_header_html( 'bulk_price_converter' );
|
||||
echo $result_message;
|
||||
echo '<form method="post" action="">';
|
||||
$data_table = array();
|
||||
$data_table[] = array(
|
||||
__( 'Multiply all product prices by', 'woocommerce-jetpack' ),
|
||||
'<input class="" type="number" step="0.000001" min="0.000001" name="multiply_prices_by" id="multiply_prices_by" value="' .
|
||||
$multiply_prices_by . '">',
|
||||
'',
|
||||
);
|
||||
|
||||
$selected_option_price_types = ( isset( $_POST['wcj_price_types'] ) ) ? $_POST['wcj_price_types'] : '';
|
||||
$data_table[] = array(
|
||||
__( 'Price type to modify', 'woocommerce-jetpack' ),
|
||||
'<select name="wcj_price_types">' .
|
||||
'<option value="wcj_both">' . __( 'Both', 'woocommerce-jetpack' ) . '</option>' .
|
||||
'<option value="wcj_sale_prices"' . selected( 'wcj_sale_prices', $selected_option_price_types, false ) . '>'
|
||||
. __( 'Sale prices only', 'woocommerce-jetpack' ) . '</option>' .
|
||||
'<option value="wcj_regular_prices"' . selected( 'wcj_regular_prices', $selected_option_price_types, false ) . '>'
|
||||
. __( 'Regular prices only', 'woocommerce-jetpack' ) . '</option>' .
|
||||
'</select>',
|
||||
'',
|
||||
);
|
||||
|
||||
if ( '' != $select_options_html ) {
|
||||
$data_table[] = array(
|
||||
__( 'Products category', 'woocommerce-jetpack' ),
|
||||
'<select name="wcj_product_cat" ' . apply_filters( 'booster_option', 'disabled', '' ) . '>' .
|
||||
'<option value="wcj_any">' . __( 'Any', 'woocommerce-jetpack' ) . '</option>' .
|
||||
$select_options_html .
|
||||
'<option value="wcj_none"' . selected( 'wcj_none', $selected_option, false ) . '>' . __( 'None', 'woocommerce-jetpack' ) . '</option>' .
|
||||
'</select>',
|
||||
apply_filters( 'booster_message', '', 'desc' ),
|
||||
);
|
||||
}
|
||||
$make_pretty_prices_threshold = isset( $_POST['make_pretty_prices_threshold'] ) ? $_POST['make_pretty_prices_threshold'] : 0;
|
||||
$data_table[] = array(
|
||||
__( '"Pretty prices" threshold', 'woocommerce-jetpack' ),
|
||||
'<input class="" type="number" step="0.000001" min="0" name="make_pretty_prices_threshold" id="make_pretty_prices_threshold" value="' .
|
||||
$make_pretty_prices_threshold . '"' . apply_filters( 'booster_option', 'disabled', '' ) . '>',
|
||||
( '' == apply_filters( 'booster_message', '', 'desc' ) ) ?
|
||||
'<em>' . __( 'Leave zero to disable', 'woocommerce-jetpack' ) . '</em>' :
|
||||
apply_filters( 'booster_message', '', 'desc' ),
|
||||
);
|
||||
$data_table[] = array(
|
||||
'<input class="button-primary" type="submit" name="bulk_change_prices_preview" id="bulk_change_prices_preview" value="' .
|
||||
__( 'Preview Prices', 'woocommerce-jetpack' ) . '">',
|
||||
'',
|
||||
'',
|
||||
);
|
||||
if ( isset( $_POST['bulk_change_prices_preview'] ) ) {
|
||||
$data_table[] = array(
|
||||
'<input class="button-primary" type="submit" name="bulk_change_prices" id="bulk_change_prices" value="' .
|
||||
__( 'Change Prices', 'woocommerce-jetpack' ) . '">',
|
||||
'',
|
||||
'',
|
||||
);
|
||||
}
|
||||
echo wcj_get_table_html( $data_table, array( 'table_heading_type' => 'none', ) );
|
||||
echo '</form>';
|
||||
if ( $is_preview ) echo $result_changing_prices;
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* make_pretty_price.
|
||||
*
|
||||
* @version 2.4.4
|
||||
* @since 2.4.4
|
||||
*/
|
||||
function make_pretty_price( $price ) {
|
||||
if ( 0 == $price ) {
|
||||
return $price;
|
||||
}
|
||||
$the_modified_price = round( $price );
|
||||
if ( $price < $_POST['make_pretty_prices_threshold'] ) {
|
||||
$the_modified_price -= 0.01; // E.g. 49.49 -> 48.99 and 49.50 -> 49.99
|
||||
} else {
|
||||
$mod_10 = $the_modified_price % 10;
|
||||
if ( 9 != $mod_10 ) {
|
||||
$the_modified_price = ( $mod_10 < 5 ) ?
|
||||
$the_modified_price - ( $mod_10 + 1 ) : // E.g. 114.00 -> 109.00
|
||||
$the_modified_price + ( 10 - ( $mod_10 + 1 ) ); // E.g. 115.00 -> 119.00
|
||||
}
|
||||
}
|
||||
return $the_modified_price;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Bulk_Price_Converter();
|
||||
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Visibility by Country
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_By_Country' ) ) :
|
||||
|
||||
class WCJ_Product_By_Country extends WCJ_Module_Product_By_Condition {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_by_country';
|
||||
$this->short_desc = __( 'Product Visibility by Country', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Display products by customer\'s country.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-visibility-by-country';
|
||||
$this->extra_desc = __( 'When enabled, module will add new "Booster: Product Visibility by Country" meta box to each product\'s edit page.', 'woocommerce-jetpack' );
|
||||
|
||||
$this->title = __( 'Countries', 'woocommerce-jetpack' );
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get_options_list.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function get_options_list() {
|
||||
return ( 'wc' === apply_filters( 'booster_option', 'all', get_option( 'wcj_product_by_country_country_list', 'all' ) ) ?
|
||||
WC()->countries->get_allowed_countries() : wcj_get_countries() );
|
||||
}
|
||||
|
||||
/**
|
||||
* get_check_option.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function get_check_option() {
|
||||
if ( 'manual' === apply_filters( 'booster_option', 'by_ip', get_option( 'wcj_product_by_country_selection_method', 'by_ip' ) ) ) {
|
||||
if ( '' == wcj_session_get( 'wcj_selected_country' ) ) {
|
||||
$country = wcj_get_country_by_ip();
|
||||
wcj_session_set( 'wcj_selected_country', $country );
|
||||
return $country;
|
||||
} else {
|
||||
return wcj_session_get( 'wcj_selected_country' );
|
||||
}
|
||||
} else {
|
||||
return wcj_get_country_by_ip();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_extra_frontend_filters.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function maybe_add_extra_frontend_filters() {
|
||||
if ( 'manual' === apply_filters( 'booster_option', 'by_ip', get_option( 'wcj_product_by_country_selection_method', 'by_ip' ) ) ) {
|
||||
add_action( 'init', array( $this, 'save_country_in_session' ), PHP_INT_MAX ) ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* save_country_in_session.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function save_country_in_session() {
|
||||
wcj_session_maybe_start();
|
||||
if ( isset( $_REQUEST['wcj_country_selector'] ) ) {
|
||||
wcj_session_set( 'wcj_selected_country', $_REQUEST['wcj_country_selector'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_extra_options_process.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function maybe_extra_options_process( $options ) {
|
||||
if ( in_array( 'EU', $options ) ) {
|
||||
$options = array_merge( $options, wcj_get_european_union_countries() );
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_extra_settings.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @todo (maybe) move "Country List" inside the "Admin Options" section
|
||||
*/
|
||||
function maybe_add_extra_settings() {
|
||||
return array(
|
||||
array(
|
||||
'title' => __( 'User Country Selection Options', 'woocommerce-jetpack' ),
|
||||
'type' => 'title',
|
||||
'id' => 'wcj_product_by_country_selection_options',
|
||||
),
|
||||
array(
|
||||
'title' => __( 'User Country Selection Method', 'woocommerce-jetpack' ),
|
||||
'desc_tip' => __( 'Possible values: "Automatically by IP" or "Manually".', 'woocommerce-jetpack' ),
|
||||
'desc' => sprintf(
|
||||
'<p>' . __( 'If "Manually" option is selected, you can add country selection drop box to frontend with "%s" widget or %s shortcode.', 'woocommerce-jetpack' ),
|
||||
__( 'Booster - Selector', 'woocommerce-jetpack' ),
|
||||
'<code>' . '[wcj_selector selector_type="country"]' . '</code>' ) .
|
||||
'<br>' . apply_filters( 'booster_message', '', 'desc' ) . '</p>',
|
||||
'id' => 'wcj_product_by_country_selection_method',
|
||||
'default' => 'by_ip',
|
||||
'type' => 'select',
|
||||
'options' => array(
|
||||
'by_ip' => __( 'Automatically by IP', 'woocommerce-jetpack' ),
|
||||
'manual' => __( 'Manually', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'custom_attributes' => apply_filters( 'booster_message', '', 'disabled' ),
|
||||
'css' => 'min-width:250px;',
|
||||
),
|
||||
array(
|
||||
'type' => 'sectionend',
|
||||
'id' => 'wcj_product_by_country_selection_options',
|
||||
),
|
||||
array(
|
||||
'title' => __( 'Admin Country List Options', 'woocommerce-jetpack' ),
|
||||
'type' => 'title',
|
||||
'id' => 'wcj_product_by_country_admin_country_list_options',
|
||||
),
|
||||
array(
|
||||
'title' => __( 'Country List', 'woocommerce-jetpack' ),
|
||||
'desc_tip' => __( 'This option sets which countries will be added to list in product\'s edit page. Possible values: "All countries" or "WooCommerce selling locations".', 'woocommerce-jetpack' ),
|
||||
'desc' => sprintf(
|
||||
'<p>' . __( 'If "WooCommerce selling locations" option is selected, country list will be set by <a href="%s">WooCommerce > Settings > General > Selling location(s)</a>.', 'woocommerce-jetpack' ),
|
||||
admin_url( 'admin.php?page=wc-settings' ) ) .
|
||||
'<br>' . apply_filters( 'booster_message', '', 'desc' ) . '</p>',
|
||||
'id' => 'wcj_product_by_country_country_list',
|
||||
'default' => 'all',
|
||||
'type' => 'select',
|
||||
'options' => array(
|
||||
'all' => __( 'All countries', 'woocommerce-jetpack' ),
|
||||
'wc' => __( 'WooCommerce selling locations', 'woocommerce-jetpack' ),
|
||||
),
|
||||
'custom_attributes' => apply_filters( 'booster_message', '', 'disabled' ),
|
||||
'css' => 'min-width:250px;',
|
||||
),
|
||||
array(
|
||||
'type' => 'sectionend',
|
||||
'id' => 'wcj_product_by_country_admin_country_list_options',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_By_Country();
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Availability by Date
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.9.1
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_By_Date' ) ) :
|
||||
|
||||
class WCJ_Product_By_Date extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.9.1
|
||||
* @todo per category
|
||||
* @todo per tag
|
||||
* @todo (maybe) per products sets
|
||||
* @todo redirect to custom URL when product is not available
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_by_date';
|
||||
$this->short_desc = __( 'Product Availability by Date', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set product availability by date.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-availability-by-date';
|
||||
parent::__construct();
|
||||
|
||||
$this->time_now = current_time( 'timestamp' );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// Per product meta box
|
||||
if ( 'yes' === get_option( 'wcj_product_by_date_per_product_enabled', 'no' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_validate_value' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'admin_notices', array( $this, 'validate_value_admin_notices' ) );
|
||||
$this->meta_box_validate_value = 'wcj_product_by_date_enabled';
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_product_by_date_per_product_enabled', 'no' ) || 'yes' === get_option( 'wcj_product_by_date_section_enabled', 'no' ) ) {
|
||||
// Time now
|
||||
$this->day_now = intval( date( 'j', $this->time_now ) ); // Day of the month without leading zeros: 1 to 31
|
||||
$this->month_now = intval( date( 'n', $this->time_now ) ); // Numeric representation of a month, without leading zeros: 1 through 12
|
||||
// Filters
|
||||
if ( 'non_purchasable' === get_option( 'wcj_product_by_date_action', 'non_purchasable' ) ) {
|
||||
add_filter( 'woocommerce_is_purchasable', array( $this, 'check_is_purchasable_by_date' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
add_action( 'woocommerce_single_product_summary', array( $this, 'maybe_add_unavailable_by_date_message' ), 30 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_default_date.
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @since 2.9.1
|
||||
*/
|
||||
function get_default_date( $i ) {
|
||||
$date_defaults = array(
|
||||
'1-31',
|
||||
'1-29',
|
||||
'1-31',
|
||||
'1-30',
|
||||
'1-31',
|
||||
'-',
|
||||
'-',
|
||||
'-',
|
||||
'10-30',
|
||||
'1-31',
|
||||
'1-30',
|
||||
'1-20,26-31',
|
||||
);
|
||||
return $date_defaults[ $i - 1 ];
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_get_direct_date.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 3.4.0
|
||||
*/
|
||||
function maybe_get_direct_date( $product_id ) {
|
||||
return (
|
||||
'yes' === get_option( 'wcj_product_by_date_per_product_enabled', 'no' ) &&
|
||||
'yes' === get_post_meta( $product_id, '_' . 'wcj_product_by_date_enabled', true ) &&
|
||||
'' != ( $direct_date = get_post_meta( $product_id, '_' . 'wcj_product_by_date_direct_date', true ) )
|
||||
) ? $direct_date : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_unavailable_by_date_message.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.9.1
|
||||
*/
|
||||
function maybe_add_unavailable_by_date_message() {
|
||||
$_product = wc_get_product();
|
||||
if ( ! $this->check_is_purchasable_by_date( true, $_product ) ) {
|
||||
if ( false !== ( $direct_date = $this->maybe_get_direct_date( wcj_get_product_id_or_variation_parent_id( $_product ) ) ) ) {
|
||||
$replaceable_values = array(
|
||||
'%direct_date%' => $direct_date,
|
||||
);
|
||||
$message = get_option( 'wcj_product_by_date_unavailable_message_direct_date',
|
||||
'<p style="color:red;">' . __( '%product_title% is not available until %direct_date%.', 'woocommerce-jetpack' ) . '</p>' );
|
||||
} else {
|
||||
$_date = $this->get_product_availability_this_month( $_product );
|
||||
$replaceable_values = array(
|
||||
'%date_this_month%' => $_date,
|
||||
);
|
||||
$message = ( ( '-' === $_date ) ?
|
||||
apply_filters( 'booster_option', __( '<p style="color:red;">%product_title% is not available this month.</p>', 'woocommerce-jetpack' ),
|
||||
get_option( 'wcj_product_by_date_unavailable_message_month_off',
|
||||
__( '<p style="color:red;">%product_title% is not available this month.</p>', 'woocommerce-jetpack' ) ) ) :
|
||||
apply_filters( 'booster_option', __( '<p style="color:red;">%product_title% is available only on %date_this_month% this month.</p>', 'woocommerce-jetpack' ),
|
||||
get_option( 'wcj_product_by_date_unavailable_message',
|
||||
__( '<p style="color:red;">%product_title% is available only on %date_this_month% this month.</p>', 'woocommerce-jetpack' ) ) )
|
||||
);
|
||||
}
|
||||
$replaceable_values['%product_title%'] = $_product->get_title();
|
||||
echo str_replace( array_keys( $replaceable_values ), $replaceable_values, do_shortcode( $message ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_product_availability_this_month.
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @since 2.9.1
|
||||
*/
|
||||
function get_product_availability_this_month( $_product ) {
|
||||
$product_id = wcj_get_product_id_or_variation_parent_id( $_product );
|
||||
if ( 'yes' === get_option( 'wcj_product_by_date_per_product_enabled', 'no' ) && 'yes' === get_post_meta( $product_id, '_' . 'wcj_product_by_date_enabled', true ) ) {
|
||||
return get_post_meta( $product_id, '_' . 'wcj_product_by_date_' . $this->month_now, true );
|
||||
} elseif ( 'yes' === get_option( 'wcj_product_by_date_section_enabled', 'no' ) ) {
|
||||
return get_option( 'wcj_product_by_date_' . $this->month_now, $this->get_default_date( $this->month_now ) );
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check_is_purchasable_by_date.
|
||||
*
|
||||
* @version 3.4.0
|
||||
* @since 2.9.1
|
||||
* @todo validate `wcj_product_by_date_` option before checking (or even better earlier, when option is saved by admin)
|
||||
*/
|
||||
function check_is_purchasable_by_date( $purchasable, $_product ) {
|
||||
if ( $purchasable ) {
|
||||
if ( false !== ( $direct_date = $this->maybe_get_direct_date( wcj_get_product_id_or_variation_parent_id( $_product ) ) ) ) {
|
||||
return ( $this->time_now >= strtotime( $direct_date ) );
|
||||
} else {
|
||||
$_date = $this->get_product_availability_this_month( $_product );
|
||||
if ( '-' === $_date ) {
|
||||
return false;
|
||||
} elseif ( '' == $_date ) {
|
||||
return true;
|
||||
} else {
|
||||
return wcj_check_date( $_date, array( 'day_now' => $this->day_now ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $purchasable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_By_Date();
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Availability by Time
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @since 2.8.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_By_Time' ) ) :
|
||||
|
||||
class WCJ_Product_By_Time extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @since 2.8.0
|
||||
* @todo per category
|
||||
* @todo per tag
|
||||
* @todo (maybe) per products sets
|
||||
* @todo redirect to custom URL when product is not available
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_by_time';
|
||||
$this->short_desc = __( 'Product Availability by Time', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set product availability by time.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-availability-by-time';
|
||||
parent::__construct();
|
||||
|
||||
$this->time_now = current_time( 'timestamp' );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
// Per product meta box
|
||||
if ( 'yes' === get_option( 'wcj_product_by_time_per_product_enabled', 'no' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_validate_value' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'admin_notices', array( $this, 'validate_value_admin_notices' ) );
|
||||
$this->meta_box_validate_value = 'wcj_product_by_time_enabled';
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_product_by_time_per_product_enabled', 'no' ) || 'yes' === get_option( 'wcj_product_by_time_section_enabled', 'no' ) ) {
|
||||
// Time now
|
||||
$this->day_of_week_now = intval( date( 'w', $this->time_now ) );
|
||||
$this->hours_now = intval( date( 'H', $this->time_now ) );
|
||||
$this->minutes_now = intval( date( 'i', $this->time_now ) );
|
||||
// Filters
|
||||
add_filter( 'woocommerce_is_purchasable', array( $this, 'check_is_purchasable_by_time' ), PHP_INT_MAX, 2 );
|
||||
add_action( 'woocommerce_single_product_summary', array( $this, 'maybe_add_unavailable_by_time_message' ), 30 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_default_time.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function get_default_time( $i ) {
|
||||
$time_defaults = array(
|
||||
'-',
|
||||
'8:00-19:59',
|
||||
'8:00-19:59',
|
||||
'8:00-19:59',
|
||||
'8:00-19:59',
|
||||
'8:00-9:59,12:00-17:59',
|
||||
'-',
|
||||
);
|
||||
return $time_defaults[ $i ];
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_unavailable_by_time_message.
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function maybe_add_unavailable_by_time_message() {
|
||||
$_product = wc_get_product();
|
||||
if ( ! $this->check_is_purchasable_by_time( true, $_product ) ) {
|
||||
$_time = $this->get_product_availability_this_day( $_product );
|
||||
$replaceable_values = array(
|
||||
'%time_today%' => $_time,
|
||||
'%product_title%' => $_product->get_title(),
|
||||
);
|
||||
$message = ( ( '-' === $_time ) ?
|
||||
apply_filters( 'booster_option', __( '<p style="color:red;">%product_title% is not available today.</p>', 'woocommerce-jetpack' ),
|
||||
get_option( 'wcj_product_by_time_unavailable_message_day_off',
|
||||
__( '<p style="color:red;">%product_title% is not available today.</p>', 'woocommerce-jetpack' ) ) ) :
|
||||
apply_filters( 'booster_option', __( '<p style="color:red;">%product_title% is available only at %time_today% today.</p>', 'woocommerce-jetpack' ),
|
||||
get_option( 'wcj_product_by_time_unavailable_message',
|
||||
__( '<p style="color:red;">%product_title% is available only at %time_today% today.</p>', 'woocommerce-jetpack' ) ) )
|
||||
);
|
||||
echo str_replace(
|
||||
array_keys( $replaceable_values ),
|
||||
array_values( $replaceable_values ),
|
||||
do_shortcode( $message )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_product_availability_this_day.
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @version 2.9.1
|
||||
*/
|
||||
function get_product_availability_this_day( $_product ) {
|
||||
$product_id = wcj_get_product_id_or_variation_parent_id( $_product );
|
||||
if ( 'yes' === get_option( 'wcj_product_by_time_per_product_enabled', 'no' ) && 'yes' === get_post_meta( $product_id, '_' . 'wcj_product_by_time_enabled', true ) ) {
|
||||
return get_post_meta( $product_id, '_' . 'wcj_product_by_time_' . $this->day_of_week_now, true );
|
||||
} elseif ( 'yes' === get_option( 'wcj_product_by_time_section_enabled', 'no' ) ) {
|
||||
return get_option( 'wcj_product_by_time_' . $this->day_of_week_now, $this->get_default_time( $this->day_of_week_now ) );
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check_is_purchasable_by_time.
|
||||
*
|
||||
* @version 2.9.1
|
||||
* @version 2.8.0
|
||||
* @todo validate `wcj_product_by_time_` option before checking (or even better earlier, when option is saved by admin)
|
||||
*/
|
||||
function check_is_purchasable_by_time( $purchasable, $_product ) {
|
||||
if ( $purchasable ) {
|
||||
$_time = $this->get_product_availability_this_day( $_product );
|
||||
if ( '-' === $_time ) {
|
||||
return false;
|
||||
} elseif ( '' == $_time ) {
|
||||
return true;
|
||||
} else {
|
||||
return wcj_check_time( $_time, array( 'hours_now' => $this->hours_now, 'minutes_now' => $this->minutes_now ) );
|
||||
}
|
||||
}
|
||||
return $purchasable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_By_Time();
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Visibility by User Role
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.5
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_By_User_Role' ) ) :
|
||||
|
||||
class WCJ_Product_By_User_Role extends WCJ_Module_Product_By_Condition {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.5
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_by_user_role';
|
||||
$this->short_desc = __( 'Product Visibility by User Role', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Display products by customer\'s user role.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-visibility-by-user-role';
|
||||
$this->extra_desc = __( 'When enabled, module will add new "Booster: Product Visibility by User Role" meta box to each product\'s edit page.', 'woocommerce-jetpack' );
|
||||
|
||||
$this->title = __( 'User Roles', 'woocommerce-jetpack' );
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get_options_list.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function get_options_list() {
|
||||
return wcj_get_user_roles_options();
|
||||
}
|
||||
|
||||
/**
|
||||
* get_check_option.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function get_check_option() {
|
||||
return wcj_get_current_user_all_roles();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_By_User_Role();
|
||||
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product by User
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.5.2
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_By_User' ) ) :
|
||||
|
||||
class WCJ_Product_By_User extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.5.2
|
||||
* @todo run `add_my_products_endpoint` only if module is enabled
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_by_user';
|
||||
$this->short_desc = __( 'User Products', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Let users add new products from frontend.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-by-user';
|
||||
$this->extra_desc = __( 'Use <strong>[wcj_product_add_new]</strong> shortcode to add product upload form to frontend.', 'woocommerce-jetpack' );
|
||||
parent::__construct();
|
||||
|
||||
// My Products endpoint
|
||||
register_activation_hook( __FILE__, array( $this, 'add_my_products_endpoint_flush_rewrite_rules' ) );
|
||||
register_deactivation_hook( __FILE__, array( $this, 'add_my_products_endpoint_flush_rewrite_rules' ) );
|
||||
add_filter( 'query_vars', array( $this, 'add_my_products_endpoint_query_var' ), 0 );
|
||||
add_action( 'init', array( $this, 'add_my_products_endpoint' ) );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( 'yes' === get_option( 'wcj_product_by_user_add_to_my_account', 'yes' ) ) {
|
||||
add_filter( 'woocommerce_account_menu_items', array( $this, 'add_my_products_tab_my_account_page' ) );
|
||||
add_action( 'woocommerce_account_wcj-my-products_endpoint', array( $this, 'add_my_products_content_my_account_page' ) );
|
||||
add_filter( 'the_title', array( $this, 'change_my_products_endpoint_title' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush rewrite rules on plugin activation.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function add_my_products_endpoint_flush_rewrite_rules() {
|
||||
add_rewrite_endpoint( 'wcj-my-products', EP_ROOT | EP_PAGES );
|
||||
flush_rewrite_rules();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new query var.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
* @param array $vars
|
||||
* @return array
|
||||
*/
|
||||
function add_my_products_endpoint_query_var( $vars ) {
|
||||
$vars[] = 'wcj-my-products';
|
||||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new endpoint to use inside My Account page.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
* @see https://developer.wordpress.org/reference/functions/add_rewrite_endpoint/
|
||||
*/
|
||||
function add_my_products_endpoint() {
|
||||
add_rewrite_endpoint( 'wcj-my-products', EP_ROOT | EP_PAGES );
|
||||
}
|
||||
|
||||
/*
|
||||
* Change endpoint title.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
* @param string $title
|
||||
* @return string
|
||||
* @see https://github.com/woocommerce/woocommerce/wiki/2.6-Tabbed-My-Account-page
|
||||
*/
|
||||
function change_my_products_endpoint_title( $title ) {
|
||||
global $wp_query;
|
||||
$is_endpoint = isset( $wp_query->query_vars['wcj-my-products'] );
|
||||
if ( $is_endpoint && ! is_admin() && is_main_query() && in_the_loop() && is_account_page() ) {
|
||||
// New page title.
|
||||
$title = __( 'Products', 'woocommerce-jetpack' );
|
||||
remove_filter( 'the_title', array( $this, 'change_my_products_endpoint_title' ) );
|
||||
}
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom help to add new items into an array after a selected item.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
* @param array $items
|
||||
* @param array $new_items
|
||||
* @param string $after
|
||||
* @return array
|
||||
* @see https://github.com/woocommerce/woocommerce/wiki/2.6-Tabbed-My-Account-page
|
||||
*/
|
||||
function insert_after_helper( $items, $new_items, $after ) {
|
||||
// Search for the item position and +1 since is after the selected item key.
|
||||
$position = array_search( $after, array_keys( $items ) ) + 1;
|
||||
// Insert the new item.
|
||||
$array = array_slice( $items, 0, $position, true );
|
||||
$array += $new_items;
|
||||
$array += array_slice( $items, $position, count( $items ) - $position, true );
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_my_products_tab_my_account_page.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.2
|
||||
* @todo check if any user's products exist
|
||||
*/
|
||||
function add_my_products_tab_my_account_page( $items ) {
|
||||
// $items['wcj-my-products'] = __( 'My Products', 'woocommerce-jetpack' );
|
||||
$new_items = array( 'wcj-my-products' => __( 'Products', 'woocommerce-jetpack' ) );
|
||||
return $this->insert_after_helper( $items, $new_items, 'orders' );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_my_products_content_my_account_page.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function add_my_products_content_my_account_page() {
|
||||
/* if ( ! isset( $_GET['wcj-my-products'] ) ) {
|
||||
return;
|
||||
} */
|
||||
$user_ID = get_current_user_id();
|
||||
if ( 0 == $user_ID ) {
|
||||
return;
|
||||
}
|
||||
if ( isset( $_GET['wcj_delete_product'] ) ) {
|
||||
$product_id = $_GET['wcj_delete_product'];
|
||||
$post_author_id = get_post_field( 'post_author', $product_id );
|
||||
if ( $user_ID != $post_author_id ) {
|
||||
echo '<p>' . __( 'Wrong user ID!', 'woocommerce-jetpack' ) . '</p>';
|
||||
} else {
|
||||
wp_delete_post( $product_id, true );
|
||||
}
|
||||
}
|
||||
if ( isset( $_GET['wcj_edit_product'] ) ) {
|
||||
$product_id = $_GET['wcj_edit_product'];
|
||||
$post_author_id = get_post_field( 'post_author', $product_id );
|
||||
if ( $user_ID != $post_author_id ) {
|
||||
echo '<p>' . __( 'Wrong user ID!', 'woocommerce-jetpack' ) . '</p>';
|
||||
} else {
|
||||
echo do_shortcode( '[wcj_product_add_new product_id="' . $product_id . '"]' );
|
||||
}
|
||||
}
|
||||
$offset = 0;
|
||||
$block_size = 256;
|
||||
$products = array();
|
||||
while( true ) {
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => $block_size,
|
||||
'offset' => $offset,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'author' => $user_ID,
|
||||
'fields' => 'ids',
|
||||
);
|
||||
$loop = new WP_Query( $args );
|
||||
if ( ! $loop->have_posts() ) {
|
||||
break;
|
||||
}
|
||||
foreach ( $loop->posts as $post_id ) {
|
||||
$products[ $post_id ] = array(
|
||||
'title' => get_the_title( $post_id ),
|
||||
'status' => get_post_status( $post_id ),
|
||||
);
|
||||
}
|
||||
$offset += $block_size;
|
||||
}
|
||||
if ( 0 != count( $products ) ) {
|
||||
// echo '<h2>' . __( 'My Products', 'woocommerce-jetpack' ) . '</h2>';
|
||||
$table_data = array();
|
||||
$table_data[] = array( '', __( 'Status', 'woocommerce-jetpack' ), __( 'Title', 'woocommerce-jetpack' ), __( 'Actions', 'woocommerce-jetpack' ) );
|
||||
$i = 0;
|
||||
foreach ( $products as $_product_id => $_product_data ) {
|
||||
$i++;
|
||||
$table_data[] = array(
|
||||
/* $i . ' [' . $_product_id . ']' . */ get_the_post_thumbnail( $_product_id, array( 25, 25 ) ),
|
||||
'<code>'. $_product_data['status'] . '</code>',
|
||||
$_product_data['title'],
|
||||
'<a class="button" href="' . add_query_arg( 'wcj_edit_product', $_product_id, remove_query_arg( array( 'wcj_edit_product_image_delete', 'wcj_delete_product' ) ) ) . '">' . __( 'Edit', 'woocommerce-jetpack' ) . '</a>' . ' ' .
|
||||
'<a class="button" href="' . add_query_arg( 'wcj_delete_product', $_product_id, remove_query_arg( array( 'wcj_edit_product_image_delete', 'wcj_edit_product' ) ) ) . '" onclick="return confirm(\'' . __( 'Are you sure?', 'woocommerce-jetpack' ) . '\')">' . __( 'Delete', 'woocommerce-jetpack' ) . '</a>',
|
||||
);
|
||||
}
|
||||
echo wcj_get_table_html( $table_data, array( 'table_class' => 'shop_table shop_table_responsive my_account_orders' ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_By_User();
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Info
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.4.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Custom_info' ) ) :
|
||||
|
||||
class WCJ_Product_Custom_info extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_custom_info';
|
||||
$this->short_desc = __( 'Product Info', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add additional info to category and single product pages.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-info';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
$single_or_archive_array = array( 'single', 'archive' );
|
||||
foreach ( $single_or_archive_array as $single_or_archive ) {
|
||||
$default_hook = ( 'single' === $single_or_archive ) ? 'woocommerce_after_single_product_summary' : 'woocommerce_after_shop_loop_item_title';
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_product_custom_info_total_number_' . $single_or_archive, 1 ) ); $i++ ) {
|
||||
add_action(
|
||||
get_option( 'wcj_product_custom_info_hook_' . $single_or_archive . '_' . $i, $default_hook ),
|
||||
array( $this, 'add_product_custom_info' ),
|
||||
get_option( 'wcj_product_custom_info_priority_' . $single_or_archive . '_' . $i, 10 )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* is_visible.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function is_visible( $product_id, $current_filter, $current_filter_priority, $default_hook, $single_or_archive, $i ) {
|
||||
return (
|
||||
$this->check_content_and_filter( $current_filter, $current_filter_priority, $default_hook, $single_or_archive, $i ) &&
|
||||
$this->check_included_and_excluded( $product_id, $single_or_archive, $i )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* check_content_and_filter.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function check_content_and_filter( $current_filter, $current_filter_priority, $default_hook, $single_or_archive, $i ) {
|
||||
return (
|
||||
'' != get_option( 'wcj_product_custom_info_content_' . $single_or_archive . '_' . $i ) &&
|
||||
$current_filter === get_option( 'wcj_product_custom_info_hook_' . $single_or_archive . '_' . $i, $default_hook ) &&
|
||||
$current_filter_priority == get_option( 'wcj_product_custom_info_priority_' . $single_or_archive . '_' . $i, 10 )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* check_included_and_excluded.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function check_included_and_excluded( $product_id, $single_or_archive, $i ) {
|
||||
$product_cats_to_include = wcj_maybe_convert_string_to_array( get_option( 'wcj_product_custom_info_product_cats_to_include_' . $single_or_archive . '_' . $i ) );
|
||||
$product_cats_to_exclude = wcj_maybe_convert_string_to_array( get_option( 'wcj_product_custom_info_product_cats_to_exclude_' . $single_or_archive . '_' . $i ) );
|
||||
$product_tags_to_include = wcj_maybe_convert_string_to_array( get_option( 'wcj_product_custom_info_product_tags_to_include_' . $single_or_archive . '_' . $i ) );
|
||||
$product_tags_to_exclude = wcj_maybe_convert_string_to_array( get_option( 'wcj_product_custom_info_product_tags_to_exclude_' . $single_or_archive . '_' . $i ) );
|
||||
$products_to_exclude = wcj_maybe_convert_string_to_array( get_option( 'wcj_product_custom_info_products_to_exclude_' . $single_or_archive . '_' . $i ) );
|
||||
$products_to_include = wcj_maybe_convert_string_to_array( get_option( 'wcj_product_custom_info_products_to_include_' . $single_or_archive . '_' . $i ) );
|
||||
return (
|
||||
( empty( $product_cats_to_exclude ) || ! wcj_is_product_term( $product_id, $product_cats_to_exclude, 'product_cat' ) ) &&
|
||||
( empty( $product_cats_to_include ) || wcj_is_product_term( $product_id, $product_cats_to_include, 'product_cat' ) ) &&
|
||||
( empty( $product_tags_to_exclude ) || ! wcj_is_product_term( $product_id, $product_tags_to_exclude, 'product_tag' ) ) &&
|
||||
( empty( $product_tags_to_include ) || wcj_is_product_term( $product_id, $product_tags_to_include, 'product_tag' ) ) &&
|
||||
( empty( $products_to_exclude ) || ! in_array( $product_id, $products_to_exclude ) ) &&
|
||||
( empty( $products_to_include ) || in_array( $product_id, $products_to_include ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* add_product_custom_info.
|
||||
*
|
||||
* @version 2.9.0
|
||||
*/
|
||||
function add_product_custom_info() {
|
||||
$product_id = get_the_ID();
|
||||
$current_filter = current_filter();
|
||||
$current_filter_priority = wcj_current_filter_priority();
|
||||
$single_or_archive_array = array( 'single', 'archive' );
|
||||
foreach ( $single_or_archive_array as $single_or_archive ) {
|
||||
$default_hook = ( 'single' === $single_or_archive ) ? 'woocommerce_after_single_product_summary' : 'woocommerce_after_shop_loop_item_title';
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_product_custom_info_total_number_' . $single_or_archive, 1 ) ); $i++ ) {
|
||||
if ( $this->is_visible( $product_id, $current_filter, $current_filter_priority, $default_hook, $single_or_archive, $i ) ) {
|
||||
echo do_shortcode( get_option( 'wcj_product_custom_info_content_' . $single_or_archive . '_' . $i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Custom_info();
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Custom Visibility
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.2.4
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Custom_Visibility' ) ) :
|
||||
|
||||
class WCJ_Product_Custom_Visibility extends WCJ_Module_Product_By_Condition {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_custom_visibility';
|
||||
$this->short_desc = __( 'Product Custom Visibility', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Display products by custom param.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-custom-visibility';
|
||||
$this->extra_desc = __( 'When enabled, module will add new "Booster: Product Custom Visibility" meta box to each product\'s edit page.', 'woocommerce-jetpack' ) . '<br>' .
|
||||
sprintf(
|
||||
__( 'You can add selection drop box to frontend with "%s" widget (set "Product custom visibility" as "Selector Type") or %s shortcode.', 'woocommerce-jetpack' ),
|
||||
__( 'Booster - Selector', 'woocommerce-jetpack' ),
|
||||
'<code>' . '[wcj_selector selector_type="product_custom_visibility"]' . '</code>' );
|
||||
|
||||
$this->title = __( 'Custom Visibility', 'woocommerce-jetpack' );
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get_options_list.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function get_options_list() {
|
||||
return wcj_get_select_options( get_option( 'wcj_product_custom_visibility_options_list', '' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* get_check_option.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function get_check_option() {
|
||||
return wcj_session_get( 'wcj_selected_product_custom_visibility' );
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_extra_frontend_filters.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function maybe_add_extra_frontend_filters() {
|
||||
add_action( 'init', array( $this, 'save_selection_in_session' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
/**
|
||||
* save_selection_in_session.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function save_selection_in_session() {
|
||||
wcj_session_maybe_start();
|
||||
if ( isset( $_REQUEST['wcj_product_custom_visibility_selector'] ) ) {
|
||||
wcj_session_set( 'wcj_selected_product_custom_visibility', $_REQUEST['wcj_product_custom_visibility_selector'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_extra_settings.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function maybe_add_extra_settings() {
|
||||
return array(
|
||||
array(
|
||||
'title' => __( 'Options List', 'woocommerce-jetpack' ),
|
||||
'type' => 'title',
|
||||
'id' => 'wcj_product_custom_visibility_options_list_options',
|
||||
),
|
||||
array(
|
||||
'title' => __( 'Options', 'woocommerce-jetpack' ),
|
||||
'desc_tip' => __( 'One per line.', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Can not be empty. Options will be added to each product\'s admin edit page and to the selection drop box on frontend.', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_product_custom_visibility_options_list',
|
||||
'default' => '',
|
||||
'type' => 'textarea',
|
||||
'css' => 'height:200px;',
|
||||
),
|
||||
array(
|
||||
'type' => 'sectionend',
|
||||
'id' => 'wcj_product_custom_visibility_options_list_options',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Custom_Visibility();
|
||||
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Images
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Images' ) ) :
|
||||
|
||||
class WCJ_Product_Images extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @todo add watermarks to images (http://php.net/manual/en/image.examples-watermark.php); Filter: `wp_get_attachment_image_src`.
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_images';
|
||||
$this->short_desc = __( 'Product Images', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Customize products images and thumbnails.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-images';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
// Single
|
||||
if ( 'yes' === get_option( 'wcj_product_images_and_thumbnails_hide_on_single', 'no' ) ) {
|
||||
add_action( 'init', array( $this, 'product_images_and_thumbnails_hide_on_single' ), PHP_INT_MAX );
|
||||
} else {
|
||||
if ( WCJ_IS_WC_VERSION_BELOW_3 ) {
|
||||
add_filter( 'woocommerce_single_product_image_html', array( $this, 'customize_single_product_image_html' ), PHP_INT_MAX, 2 ); // filter doesn't exist in WC3
|
||||
add_filter( 'woocommerce_single_product_image_thumbnail_html', array( $this, 'customize_single_product_image_thumbnail_html' ) );
|
||||
} else {
|
||||
add_filter( 'woocommerce_single_product_image_thumbnail_html', array( $this, 'customize_single_product_image_or_thumbnail_html_wc3' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
// Archives
|
||||
add_action( 'woocommerce_before_shop_loop_item', array( $this, 'product_images_hide_on_archive' ) );
|
||||
add_action( 'woocommerce_before_shop_loop_item_title', array( $this, 'customize_archive_product_image_html' ), 10 );
|
||||
add_action( 'woocommerce_before_shop_loop_item_title', array( $this, 'hide_per_product_image_on_archives_start' ), 1 );
|
||||
add_action( 'woocommerce_before_shop_loop_item_title', array( $this, 'hide_per_product_image_on_archives_end' ), PHP_INT_MAX );
|
||||
|
||||
// Single Product Thumbnails Columns Number
|
||||
add_filter( 'woocommerce_product_thumbnails_columns', array( $this, 'change_product_thumbnails_columns_number' ), PHP_INT_MAX );
|
||||
|
||||
// Per product options
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_per_product_image_on_archives_start.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function hide_per_product_image_on_archives_start() {
|
||||
$post_id = get_the_ID();
|
||||
if ( $post_id > 0 && 'yes' === get_post_meta( $post_id, '_' . 'wcj_product_images_hide_image_on_archives', true ) ) {
|
||||
remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_per_product_image_on_archives_end.
|
||||
*
|
||||
* @version 2.5.2
|
||||
* @since 2.5.2
|
||||
*/
|
||||
function hide_per_product_image_on_archives_end() {
|
||||
$post_id = get_the_ID();
|
||||
if ( $post_id > 0 && 'yes' === get_post_meta( $post_id, '_' . 'wcj_product_images_hide_image_on_archives', true ) ) {
|
||||
add_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* customize_archive_product_image_html.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.2.6
|
||||
*/
|
||||
function customize_archive_product_image_html() {
|
||||
$post_id = get_the_ID();
|
||||
if ( $post_id > 0 && '' != get_post_meta( $post_id, '_' . 'wcj_product_images_meta_custom_on_archives', true ) ) {
|
||||
echo do_shortcode( get_post_meta( $post_id, '_' . 'wcj_product_images_meta_custom_on_archives', true ) );
|
||||
} elseif ( '' != get_option( 'wcj_product_images_custom_on_archives', '' ) ) {
|
||||
echo do_shortcode( get_option( 'wcj_product_images_custom_on_archives' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* product_images_hide_on_archive.
|
||||
*
|
||||
* @version 2.2.6
|
||||
*/
|
||||
function product_images_hide_on_archive() {
|
||||
if (
|
||||
'yes' === get_option( 'wcj_product_images_hide_on_archive', 'no' ) ||
|
||||
'' != get_option( 'wcj_product_images_custom_on_archives', '' ) ||
|
||||
( ( $post_id = get_the_ID() ) > 0 && '' != get_post_meta( $post_id, '_' . 'wcj_product_images_meta_custom_on_archives', true ) )
|
||||
) {
|
||||
remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* product_images_and_thumbnails_hide_on_single.
|
||||
*/
|
||||
function product_images_and_thumbnails_hide_on_single() {
|
||||
remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_images', 20 );
|
||||
}
|
||||
|
||||
/**
|
||||
* customize_single_product_image_html.
|
||||
*
|
||||
* @version 2.9.0
|
||||
*/
|
||||
function customize_single_product_image_html( $image_link, $post_id ) {
|
||||
if ( '' != ( $html_single = get_post_meta( $post_id, '_' . 'wcj_product_images_meta_custom_on_single', true ) ) ) {
|
||||
return do_shortcode( $html_single );
|
||||
} elseif ( '' != ( $html_global = get_option( 'wcj_product_images_custom_on_single', '' ) ) ) {
|
||||
return do_shortcode( $html_global );
|
||||
} elseif ( 'yes' === get_option( 'wcj_product_images_hide_on_single', 'no' ) ) {
|
||||
return '';
|
||||
} elseif ( 'yes' === get_post_meta( $post_id, '_' . 'wcj_product_images_hide_image_on_single', true ) ) {
|
||||
return '';
|
||||
}
|
||||
return $image_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* customize_single_product_image_thumbnail_html.
|
||||
*
|
||||
* @version 2.9.0
|
||||
*/
|
||||
function customize_single_product_image_thumbnail_html( $image_link ) {
|
||||
$post_id = get_the_ID();
|
||||
if ( '' != get_option( 'wcj_product_images_thumbnails_custom_on_single', '' ) ) {
|
||||
return do_shortcode( get_option( 'wcj_product_images_thumbnails_custom_on_single' ) );
|
||||
} elseif ( 'yes' === get_option( 'wcj_product_images_thumbnails_hide_on_single', 'no' ) ) {
|
||||
return '';
|
||||
} elseif ( $post_id > 0 && 'yes' === get_post_meta( $post_id, '_' . 'wcj_product_images_hide_thumb_on_single', true ) ) {
|
||||
return '';
|
||||
}
|
||||
return $image_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* customize_single_product_image_or_thumbnail_html_wc3.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function customize_single_product_image_or_thumbnail_html_wc3( $html, $attachment_id ) {
|
||||
$post_id = get_the_ID();
|
||||
return ( get_post_thumbnail_id( $post_id ) === $attachment_id ?
|
||||
$this->customize_single_product_image_html( $html, $post_id ) :
|
||||
$this->customize_single_product_image_thumbnail_html( $html )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* change_product_thumbnails_columns.
|
||||
*/
|
||||
function change_product_thumbnails_columns_number( $columns_number ) {
|
||||
return get_option( 'wcj_product_images_thumbnails_columns', 3 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Images();
|
||||
@@ -0,0 +1,307 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Info V1
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @author Algoritmika Ltd.
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Info' ) ) :
|
||||
|
||||
class WCJ_Product_Info extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* search_and_replace_deprecated_shortcodes.
|
||||
*
|
||||
* @version 2.4.0
|
||||
* @since 2.4.0
|
||||
*/
|
||||
private function search_and_replace_deprecated_shortcodes( $data ) {
|
||||
$search_and_replace_deprecated_shortcodes_array = array(
|
||||
'%sku%' => '[wcj_product_sku]',
|
||||
'wcj_sku' => 'wcj_product_sku',
|
||||
'%title%' => '[wcj_product_title]',
|
||||
'wcj_title' => 'wcj_product_title',
|
||||
'%weight%' => '[wcj_product_weight]',
|
||||
'wcj_weight' => 'wcj_product_weight',
|
||||
'%total_sales%' => '[wcj_product_total_sales]',
|
||||
'wcj_total_sales' => 'wcj_product_total_sales',
|
||||
'%shipping_class%' => '[wcj_product_shipping_class]',
|
||||
'wcj_shipping_class' => 'wcj_product_shipping_class',
|
||||
'%dimensions%' => '[wcj_product_dimensions]',
|
||||
'wcj_dimensions' => 'wcj_product_dimensions',
|
||||
'%formatted_name%' => '[wcj_product_formatted_name]',
|
||||
'wcj_formatted_name' => 'wcj_product_formatted_name',
|
||||
'%stock_availability%' => '[wcj_product_stock_availability]',
|
||||
'wcj_stock_availability' => 'wcj_product_stock_availability',
|
||||
'%tax_class%' => '[wcj_product_tax_class]',
|
||||
'wcj_tax_class' => 'wcj_product_tax_class',
|
||||
'%average_rating%' => '[wcj_product_average_rating]',
|
||||
'wcj_average_rating' => 'wcj_product_average_rating',
|
||||
'%categories%' => '[wcj_product_categories]',
|
||||
'wcj_categories' => 'wcj_product_categories',
|
||||
'%list_attributes%' => '[wcj_product_list_attributes]',
|
||||
'wcj_list_attributes' => 'wcj_product_list_attributes',
|
||||
// '%list_attribute%' => '[wcj_product_list_attribute]',
|
||||
'wcj_list_attribute options=' => 'wcj_product_list_attribute name=',
|
||||
'wcjp_list_attribute attribute_name=' => 'wcj_product_list_attribute name=',
|
||||
'%stock_quantity%' => '[wcj_product_stock_quantity]',
|
||||
'wcj_stock_quantity' => 'wcj_product_stock_quantity',
|
||||
'%sale_price%' => '[wcj_product_sale_price hide_currency="yes"]',
|
||||
'wcj_sale_price' => 'wcj_product_sale_price hide_currency="yes"',
|
||||
'%sale_price_formatted%' => '[wcj_product_sale_price]',
|
||||
'wcj_sale_price_formatted' => 'wcj_product_sale_price',
|
||||
'%regular_price%' => '[wcj_product_regular_price hide_currency="yes"]',
|
||||
'wcj_regular_price' => 'wcj_product_regular_price hide_currency="yes"',
|
||||
'%regular_price_formatted%' => '[wcj_product_regular_price]',
|
||||
'wcj_regular_price_formatted' => 'wcj_product_regular_price',
|
||||
'%regular_price_if_on_sale%' => '[wcj_product_regular_price hide_currency="yes" show_always="no"]',
|
||||
'wcj_regular_price_if_on_sale' => 'wcj_product_regular_price hide_currency="yes" show_always="no"',
|
||||
'%regular_price_if_on_sale_formatted%' => '[wcj_product_regular_price show_always="no"]',
|
||||
'wcj_regular_price_if_on_sale_formatted' => 'wcj_product_regular_price show_always="no"',
|
||||
'%time_since_last_sale%' => '[wcj_product_time_since_last_sale]',
|
||||
'wcj_time_since_last_sale' => 'wcj_product_time_since_last_sale',
|
||||
'%price_including_tax%' => '[wcj_product_price_including_tax hide_currency="yes"]',
|
||||
'wcj_price_including_tax' => 'wcj_product_price_including_tax hide_currency="yes"',
|
||||
'%price_including_tax_formatted%' => '[wcj_product_price_including_tax]',
|
||||
'wcj_price_including_tax_formatted' => 'wcj_product_price_including_tax',
|
||||
'%price_excluding_tax%' => '[wcj_product_price_excluding_tax hide_currency="yes"]',
|
||||
'wcj_price_excluding_tax' => 'wcj_product_price_excluding_tax hide_currency="yes"',
|
||||
'%price_excluding_tax_formatted%' => '[wcj_product_price_excluding_tax]',
|
||||
'wcj_price_excluding_tax_formatted' => 'wcj_product_price_excluding_tax',
|
||||
'%price%' => '[wcj_product_price hide_currency="yes"]',
|
||||
'wcj_price' => 'wcj_product_price hide_currency="yes"',
|
||||
'%price_formatted%' => '[wcj_product_price]',
|
||||
'wcj_price_formatted' => 'wcj_product_price',
|
||||
'%you_save%' => '[wcj_product_you_save hide_currency="yes"]',
|
||||
'wcj_you_save' => 'wcj_product_you_save hide_currency="yes"',
|
||||
'%you_save_formatted%' => '[wcj_product_you_save]',
|
||||
'wcj_you_save_formatted' => 'wcj_product_you_save',
|
||||
'%you_save_percent%' => '[wcj_product_you_save_percent]',
|
||||
'wcj_you_save_percent' => 'wcj_product_you_save_percent',
|
||||
'wcj_available_variations' => 'wcj_product_available_variations',
|
||||
);
|
||||
return str_replace(
|
||||
array_keys( $search_and_replace_deprecated_shortcodes_array ),
|
||||
array_values( $search_and_replace_deprecated_shortcodes_array ),
|
||||
$data
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_info';
|
||||
$this->short_desc = __( 'Product Info V1', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add additional info to category and single product pages.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-info';
|
||||
parent::__construct();
|
||||
|
||||
$this->product_info_on_archive_filters_array = $this->get_product_info_on_archive_filters_array();
|
||||
$this->product_info_on_single_filters_array = $this->get_product_info_on_single_filters_array();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
$this->add_product_info_filters( 'archive' );
|
||||
$this->add_product_info_filters( 'single' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_product_info_on_archive_filters_array.
|
||||
*
|
||||
* @version 2.4.0
|
||||
* @since 2.4.0
|
||||
*/
|
||||
private function get_product_info_on_archive_filters_array() {
|
||||
return array(
|
||||
'woocommerce_before_shop_loop_item' => __( 'Before product', 'woocommerce-jetpack' ),
|
||||
'woocommerce_before_shop_loop_item_title' => __( 'Before product title', 'woocommerce-jetpack' ),
|
||||
'woocommerce_after_shop_loop_item' => __( 'After product', 'woocommerce-jetpack' ),
|
||||
'woocommerce_after_shop_loop_item_title' => __( 'After product title', 'woocommerce-jetpack' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* get_product_info_on_single_filters_array.
|
||||
*
|
||||
* @version 2.4.0
|
||||
* @since 2.4.0
|
||||
*/
|
||||
private function get_product_info_on_single_filters_array() {
|
||||
return array(
|
||||
'woocommerce_single_product_summary' => __( 'Inside single product summary', 'woocommerce-jetpack' ),
|
||||
'woocommerce_before_single_product_summary' => __( 'Before single product summary', 'woocommerce-jetpack' ),
|
||||
'woocommerce_after_single_product_summary' => __( 'After single product summary', 'woocommerce-jetpack' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* add_product_info_filters.
|
||||
*/
|
||||
function add_product_info_filters( $single_or_archive ) {
|
||||
// Product Info
|
||||
if ( ( 'yes' === get_option( 'wcj_product_info_on_' . $single_or_archive . '_enabled' ) ) &&
|
||||
( '' != get_option( 'wcj_product_info_on_' . $single_or_archive ) ) &&
|
||||
( '' != get_option( 'wcj_product_info_on_' . $single_or_archive . '_filter' ) ) &&
|
||||
( '' != get_option( 'wcj_product_info_on_' . $single_or_archive . '_filter_priority' ) ) )
|
||||
add_action( get_option( 'wcj_product_info_on_' . $single_or_archive . '_filter' ), array( $this, 'product_info' ), get_option( 'wcj_product_info_on_' . $single_or_archive . '_filter_priority' ) );
|
||||
// More product Info
|
||||
if ( 'yes' === get_option( 'wcj_more_product_info_on_' . $single_or_archive . '_enabled' ) ) {
|
||||
add_action( get_option( 'wcj_more_product_info_on_' . $single_or_archive . '_filter' ), array( $this, 'more_product_info' ), get_option( 'wcj_more_product_info_on_' . $single_or_archive . '_filter_priority' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* product_info.
|
||||
*
|
||||
* @version 2.4.0
|
||||
*/
|
||||
function product_info() {
|
||||
$the_action_name = current_filter();
|
||||
if ( array_key_exists( $the_action_name, $this->product_info_on_archive_filters_array ) ) {
|
||||
$the_product_info = get_option( 'wcj_product_info_on_archive' );
|
||||
$the_product_info = $this->search_and_replace_deprecated_shortcodes( $the_product_info );
|
||||
$this->apply_product_info_short_codes( $the_product_info, false );
|
||||
}
|
||||
else if ( array_key_exists( $the_action_name, $this->product_info_on_single_filters_array ) ) {
|
||||
$the_product_info = get_option( 'wcj_product_info_on_single' );
|
||||
$the_product_info = $this->search_and_replace_deprecated_shortcodes( $the_product_info );
|
||||
$this->apply_product_info_short_codes( $the_product_info, false );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* more_product_info.
|
||||
*/
|
||||
function more_product_info() {
|
||||
$the_action_name = current_filter();
|
||||
if ( array_key_exists( $the_action_name, $this->product_info_on_archive_filters_array ) )
|
||||
$this->add_more_product_info( 'archive' );
|
||||
else if ( array_key_exists( $the_action_name, $this->product_info_on_single_filters_array ) )
|
||||
$this->add_more_product_info( 'single' );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_more_product_info.
|
||||
*
|
||||
* @version 2.4.0
|
||||
*/
|
||||
function add_more_product_info( $single_or_archive ) {
|
||||
//$single_or_archive = 'archive';
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 4, get_option( 'wcj_more_product_info_on_' . $single_or_archive . '_fields_total', 4 ) ); $i++ ) {
|
||||
$field_id = 'wcj_more_product_info_on_' . $single_or_archive . '_' . $i ;
|
||||
$the_product_info = get_option( $field_id );
|
||||
$the_product_info = $this->search_and_replace_deprecated_shortcodes( $the_product_info );
|
||||
$this->apply_product_info_short_codes( $the_product_info, true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* apply_product_info_short_codes.
|
||||
*
|
||||
* @version 2.4.0
|
||||
*/
|
||||
function apply_product_info_short_codes( $the_product_info, $remove_on_empty ) {
|
||||
|
||||
$product_ids_to_exclude = get_option( 'wcj_product_info_products_to_exclude', '' );
|
||||
if ( '' != $product_ids_to_exclude ) {
|
||||
$product_ids_to_exclude = str_replace( ' ', '', $product_ids_to_exclude );
|
||||
$product_ids_to_exclude = explode( ',', $product_ids_to_exclude );
|
||||
$product_id = get_the_ID();
|
||||
if ( ! empty( $product_ids_to_exclude ) && is_array( $product_ids_to_exclude ) && in_array( $product_id, $product_ids_to_exclude ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( '' == $the_product_info ) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo do_shortcode( $the_product_info );
|
||||
}
|
||||
|
||||
/**
|
||||
* admin_add_product_info_fields_with_header.
|
||||
*/
|
||||
function admin_add_product_info_fields_with_header( &$settings, $single_or_archive, $title, $filters_array ) {
|
||||
$settings = array_merge( $settings, array(
|
||||
array(
|
||||
'title' => $title,
|
||||
'desc' => __( 'Enable', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_more_product_info_on_' . $single_or_archive . '_enabled',
|
||||
'default' => 'no',
|
||||
'type' => 'checkbox',
|
||||
),
|
||||
array(
|
||||
'title' => '',
|
||||
'desc' => __( 'Position', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_more_product_info_on_' . $single_or_archive . '_filter',
|
||||
'css' => 'min-width:350px;',
|
||||
'class' => 'chosen_select',
|
||||
'default' => 'woocommerce_after_shop_loop_item_title',
|
||||
'type' => 'select',
|
||||
'options' => $filters_array, //$this->product_info_on_archive_filters_array,
|
||||
'desc_tip' => true,
|
||||
),
|
||||
array(
|
||||
'title' => '',
|
||||
'desc_tip' => __( 'Priority (i.e. Order)', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_more_product_info_on_' . $single_or_archive . '_filter_priority',
|
||||
'default' => 10,
|
||||
'type' => 'number',
|
||||
),
|
||||
array(
|
||||
'title' => '',
|
||||
'desc_tip' => __( 'Number of product info fields. Click "Save changes" after you change this number.', 'woocommerce-jetpack' ),
|
||||
'id' => 'wcj_more_product_info_on_' . $single_or_archive . '_fields_total',
|
||||
'default' => 4,
|
||||
'type' => 'number',
|
||||
'desc' => apply_filters( 'booster_message', '', 'desc' ),
|
||||
'custom_attributes' => apply_filters( 'booster_message', '', 'readonly' ),
|
||||
),
|
||||
) );
|
||||
$this->admin_add_product_info_fields( $settings, $single_or_archive );
|
||||
}
|
||||
|
||||
/**
|
||||
* admin_add_product_info_fields.
|
||||
*
|
||||
* @version 2.4.0
|
||||
*/
|
||||
function admin_add_product_info_fields( &$settings, $single_or_archive ) {
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 4, get_option( 'wcj_more_product_info_on_' . $single_or_archive . '_fields_total', 4 ) ); $i++ ) {
|
||||
$field_id = 'wcj_more_product_info_on_' . $single_or_archive . '_' . $i ;
|
||||
$default_value = '';
|
||||
switch ( $i ) {
|
||||
case 1: $default_value = '<ul>'; break;
|
||||
case 2: $default_value = '<li>' . __( '[wcj_product_you_save before="You save: <strong>" hide_if_zero="yes" after="</strong>"][wcj_product_you_save_percent hide_if_zero="yes" before=" (" after="%)"]', 'woocommerce-jetpack' ) . '</li>'; break;
|
||||
case 3: $default_value = '<li>' . __( '[wcj_product_total_sales before="Total sales: "]', 'woocommerce-jetpack' ) . '</li>'; break;
|
||||
case 4: $default_value = '</ul>'; break;
|
||||
}
|
||||
// $desc = ( '' != $default_value ) ? __( 'Default', 'woocommerce-jetpack' ) . ': ' . esc_html( $default_value ) : '';
|
||||
// $short_codes_list = '%you_save%, %total_sales%';
|
||||
// $desc_tip = __( 'Field Nr. ', 'woocommerce-jetpack' ) . $i . '<br>' . __( 'Available short codes: ', 'woocommerce-jetpack' ) . $short_codes_list;
|
||||
$settings[] = array(
|
||||
'title' => '',
|
||||
// 'desc_tip' => $desc_tip,
|
||||
// 'desc' => $desc,
|
||||
'id' => $field_id,
|
||||
'default' => $default_value,
|
||||
'type' => 'textarea',
|
||||
'css' => 'width:50%;min-width:300px;',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Info();
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Input Fields
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Input_Fields' ) ) :
|
||||
|
||||
class WCJ_Product_Input_Fields extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @todo (maybe) option to change local and global fields order (i.e. output local fields before the global)
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_input_fields';
|
||||
$this->short_desc = __( 'Product Input Fields', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add input fields to the products.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-input-fields';
|
||||
parent::__construct();
|
||||
|
||||
require_once( 'input-fields/class-wcj-product-input-fields-core.php' );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
add_action( 'woocommerce_delete_order_items', array( $this, 'delete_file_uploads' ) );
|
||||
|
||||
add_action( 'init', array( $this, 'handle_downloads' ) );
|
||||
|
||||
$this->global_product_fields = new WCJ_Product_Input_Fields_Core( 'global' );
|
||||
$this->local_product_fields = new WCJ_Product_Input_Fields_Core( 'local' );
|
||||
|
||||
if ( 'yes' === get_option( 'wcj_product_input_fields_global_enabled', 'no' ) || 'yes' === get_option( 'wcj_product_input_fields_local_enabled', 'no' ) ) {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'init', array( $this, 'register_scripts' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_global_product_fields_options.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function get_global_product_fields_options() {
|
||||
$this->scope = 'global';
|
||||
$return = require( 'input-fields/wcj-product-input-fields-options.php' );
|
||||
unset( $this->scope );
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete_file_uploads.
|
||||
*
|
||||
* @version 2.2.2
|
||||
* @since 2.2.2
|
||||
*/
|
||||
function delete_file_uploads( $postid ) {
|
||||
$the_order = wc_get_order( $postid );
|
||||
$the_items = $the_order->get_items();
|
||||
foreach ( $the_items as $item ) {
|
||||
foreach ( $item as $item_field ) {
|
||||
$item_field = maybe_unserialize( $item_field );
|
||||
if ( is_array( $item_field ) && isset( $item_field['wcj_type'] ) && 'file' === $item_field['wcj_type'] ) {
|
||||
unlink( $item_field['tmp_name'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle_downloads.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.2.2
|
||||
*/
|
||||
function handle_downloads() {
|
||||
if ( isset ( $_GET['wcj_download_file'] ) ) {
|
||||
$file_name = $_GET['wcj_download_file'];
|
||||
$upload_dir = wcj_get_wcj_uploads_dir( 'input_fields_uploads' );
|
||||
$file_path = $upload_dir . '/' . $file_name;
|
||||
if ( wcj_is_user_role( 'administrator' ) || is_shop_manager() ) {
|
||||
header( "Expires: 0" );
|
||||
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
|
||||
header( "Cache-Control: private", false );
|
||||
header( 'Content-disposition: attachment; filename=' . $file_name );
|
||||
header( "Content-Transfer-Encoding: binary" );
|
||||
header( "Content-Length: ". filesize( $file_path ) );
|
||||
readfile( $file_path );
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* register_script.
|
||||
*
|
||||
* @version 2.9.0
|
||||
*/
|
||||
function register_scripts() {
|
||||
wp_register_script( 'wcj-product-input-fields', wcj_plugin_url() . '/includes/js/wcj-product-input-fields.js', array( 'jquery' ), WCJ()->version, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_checkout_script.
|
||||
*/
|
||||
function enqueue_scripts() {
|
||||
if( ! is_product() ) {
|
||||
return;
|
||||
}
|
||||
wp_enqueue_script( 'wcj-product-input-fields' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Input_Fields();
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Listings
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Listings' ) ) :
|
||||
|
||||
class WCJ_Product_Listings extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @todo more descriptions in settings (i.e. Storefront etc.)
|
||||
* @todo add deprecated options (which were moved to Storefront)
|
||||
* @todo add options to enable/disable each section
|
||||
* @todo add "Exclude Categories Products" to "Category Display Options" also
|
||||
* @todo add "Exclude Products" and "Exclude Tags Products"
|
||||
*/
|
||||
function __construct() {
|
||||
$this->id = 'product_listings';
|
||||
$this->short_desc = __( 'Product Listings', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Change display options for shop and category pages: show/hide categories count, exclude categories, show/hide empty categories.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-listings';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
// Exclude and Hide Empty
|
||||
add_filter( 'woocommerce_product_subcategories_args', array( $this, 'filter_subcategories' ), 100 );
|
||||
add_filter( 'woocommerce_product_subcategories_hide_empty', array( $this, 'filter_subcategories_hide_empty' ), 100 );
|
||||
|
||||
// Hide Count
|
||||
if ( 'yes' === get_option( 'wcj_product_listings_hide_cats_count_on_shop' ) || 'yes' === get_option( 'wcj_product_listings_hide_cats_count_on_archive' ) ) {
|
||||
add_filter( 'woocommerce_subcategory_count_html', array( $this, 'remove_subcategory_count' ), 100 );
|
||||
}
|
||||
|
||||
// Product visibility by price
|
||||
if ( 'yes' === get_option( 'wcj_product_listings_product_visibility_by_price_enabled', 'no' ) ) {
|
||||
add_filter( 'woocommerce_product_is_visible', array( $this, 'product_visibility_by_price' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
// Product visibility by category
|
||||
$this->cats_products_to_hide_on_shop = get_option( 'wcj_product_listings_exclude_cats_products_on_shop', '' );
|
||||
if ( ! empty( $this->cats_products_to_hide_on_shop ) ) {
|
||||
add_filter( 'woocommerce_product_is_visible', array( $this, 'product_visibility_by_category' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* product_visibility_by_category.
|
||||
*
|
||||
* @version 3.5.0
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function product_visibility_by_category( $visible, $product_id ) {
|
||||
return ( ! isset( $_GET['s'] ) && is_shop() && wcj_is_product_term( $product_id, $this->cats_products_to_hide_on_shop, 'product_cat' ) ? false : $visible );
|
||||
}
|
||||
|
||||
/**
|
||||
* product_visibility_by_price.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.3
|
||||
* @todo grouped products
|
||||
* @todo (maybe) as new "Product Visibility by Price" module
|
||||
*/
|
||||
function product_visibility_by_price( $visible, $product_id ) {
|
||||
$product = wc_get_product( $product_id );
|
||||
if ( $product->is_type( 'variable' ) ) {
|
||||
$min_price = $product->get_variation_price( 'min' );
|
||||
$max_price = $product->get_variation_price( 'max' );
|
||||
} else {
|
||||
$min_price = $product->get_price();
|
||||
$max_price = $product->get_price();
|
||||
}
|
||||
$min_price_limit = get_option( 'wcj_product_listings_product_visibility_by_price_min', 0 );
|
||||
$max_price_limit = get_option( 'wcj_product_listings_product_visibility_by_price_max', 0 );
|
||||
return ( ( 0 != $min_price_limit && $min_price < $min_price_limit ) || ( 0 != $max_price_limit && $max_price > $max_price_limit ) ? false : $visible );
|
||||
}
|
||||
|
||||
/**
|
||||
* remove_subcategory_count.
|
||||
*/
|
||||
function remove_subcategory_count( $count_html ) {
|
||||
if (
|
||||
( is_shop() && 'yes' === get_option( 'wcj_product_listings_hide_cats_count_on_shop' ) ) ||
|
||||
( ! is_shop() && 'yes' === apply_filters( 'booster_option', 'wcj', get_option( 'wcj_product_listings_hide_cats_count_on_archive' ) ) )
|
||||
) {
|
||||
return '';
|
||||
}
|
||||
return $count_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* filter_subcategories.
|
||||
*
|
||||
* @version 2.7.0
|
||||
*/
|
||||
function filter_subcategories( $args ) {
|
||||
$args['exclude'] = ( is_shop() ) ?
|
||||
get_option( 'wcj_product_listings_exclude_cats_on_shop', '' ) :
|
||||
get_option( 'wcj_product_listings_exclude_cats_on_archives', '' );
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_products_by_disabling_loop.
|
||||
*/
|
||||
function hide_products_by_disabling_loop() {
|
||||
// If we are hiding products disable the loop and pagination
|
||||
global $wp_query;
|
||||
if (
|
||||
is_product_category() &&
|
||||
get_option( 'woocommerce_category_archive_display' ) == 'subcategories' &&
|
||||
'no' === get_option( 'wcj_product_listings_show_products_if_no_cats_on_archives' )
|
||||
) {
|
||||
$wp_query->post_count = 0;
|
||||
$wp_query->max_num_pages = 0;
|
||||
}
|
||||
if (
|
||||
is_shop() &&
|
||||
get_option( 'woocommerce_shop_page_display' ) == 'subcategories' &&
|
||||
'no' === get_option( 'wcj_product_listings_show_products_if_no_cats_on_shop' )
|
||||
) {
|
||||
$wp_query->post_count = 0;
|
||||
$wp_query->max_num_pages = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* filter_subcategories_hide_empty.
|
||||
*
|
||||
* @version 2.7.0
|
||||
*/
|
||||
function filter_subcategories_hide_empty() {
|
||||
|
||||
// Not the best solution, but it's the only place I found to put it...
|
||||
$this->hide_products_by_disabling_loop();
|
||||
|
||||
$hide_empty = ( is_shop() ) ?
|
||||
( 'yes' === get_option( 'wcj_product_listings_hide_empty_cats_on_shop', 'yes' ) ) :
|
||||
( 'yes' === get_option( 'wcj_product_listings_hide_empty_cats_on_archives', 'yes' ) );
|
||||
|
||||
return $hide_empty;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Listings();
|
||||
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product MSRP
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_MSRP' ) ) :
|
||||
|
||||
class WCJ_Product_MSRP extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @todo (maybe) option to change `_wcj_msrp` meta key
|
||||
* @todo (maybe) REST API
|
||||
* @todo (maybe) grouped products
|
||||
* @todo (maybe) composite products
|
||||
* @todo (maybe) `[wcj_product_msrp]` shortcode (and link to "Product Info" module in description)
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_msrp';
|
||||
$this->short_desc = __( 'Product MSRP', 'woocommerce-jetpack' );
|
||||
$this->extra_desc = __( 'The <strong>manufacturer\'s suggested retail price</strong> (<strong>MSRP</strong>), also known as the <strong>list price</strong>, or the <strong>recommended retail price</strong> (<strong>RRP</strong>), or the <strong>suggested retail price</strong> (<strong>SRP</strong>), of a product is the price at which the manufacturer recommends that the retailer sell the product.', 'woocommerce-jetpack' ) . '<br>' .
|
||||
sprintf( __( 'Booster stores MSRP as product meta with %s key.', 'woocommerce-jetpack' ), '<code>_wcj_msrp</code>' );
|
||||
$this->desc = __( 'Save and display product MSRP in WooCommerce.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-msrp';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( 'inline' === get_option( 'wcj_product_msrp_admin_view', 'inline' ) ) {
|
||||
// MSRP input on admin product page (simple product)
|
||||
add_action( 'woocommerce_product_options_pricing', array( $this, 'add_msrp_input' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_msrp_input' ), PHP_INT_MAX, 2 );
|
||||
// MSRP input on admin product page (variable product)
|
||||
add_action( 'woocommerce_variation_options_pricing', array( $this, 'add_msrp_input_variable' ), 10, 3 );
|
||||
add_action( 'woocommerce_save_product_variation', array( $this, 'save_msrp_input_variable' ), PHP_INT_MAX, 2 );
|
||||
} else { // 'meta_box'
|
||||
// Products meta box
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
// Display
|
||||
add_filter( 'woocommerce_get_price_html', array( $this, 'display' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* add_msrp_input_variable.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function add_msrp_input_variable( $loop, $variation_data, $variation ) {
|
||||
woocommerce_wp_text_input( array(
|
||||
'id' => "variable_wcj_msrp_{$loop}",
|
||||
'name' => "variable_wcj_msrp[{$loop}]",
|
||||
'value' => wc_format_localized_price( isset( $variation_data['_wcj_msrp'][0] ) ? $variation_data['_wcj_msrp'][0] : '' ),
|
||||
'label' => __( 'MSRP', 'woocommerce-jetpack' ) . ' (' . get_woocommerce_currency_symbol() . ')',
|
||||
'data_type' => 'price',
|
||||
'wrapper_class' => 'form-row form-row-full',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* save_msrp_input_variable.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function save_msrp_input_variable( $variation_id, $i ) {
|
||||
if ( isset( $_POST['variable_wcj_msrp'][ $i ] ) ) {
|
||||
update_post_meta( $variation_id, '_wcj_msrp', wc_clean( $_POST['variable_wcj_msrp'][ $i ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_msrp_input.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @todo (maybe) rethink `$product_id`
|
||||
*/
|
||||
function add_msrp_input() {
|
||||
$product_id = get_the_ID();
|
||||
woocommerce_wp_text_input( array(
|
||||
'id' => '_wcj_msrp',
|
||||
'value' => get_post_meta( $product_id, '_' . 'wcj_msrp', true ),
|
||||
'data_type' => 'price',
|
||||
'label' => __( 'MSRP', 'woocommerce-jetpack' ) . ' (' . get_woocommerce_currency_symbol() . ')',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* save_msrp_input.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function save_msrp_input( $post_id, $__post ) {
|
||||
if ( isset( $_POST['_wcj_msrp'] ) ) {
|
||||
update_post_meta( $post_id, '_wcj_msrp', $_POST['_wcj_msrp'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* display.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
* @todo (maybe) multicurrency
|
||||
* @todo (maybe) variable product's msrp
|
||||
*/
|
||||
function display( $price_html, $product ) {
|
||||
$section_id = ( is_product() ? 'single' : 'archives' );
|
||||
$display = get_option( 'wcj_product_msrp_display_on_' . $section_id, 'show' );
|
||||
if ( 'hide' == $display ) {
|
||||
return $price_html;
|
||||
}
|
||||
$product_id = wcj_get_product_id( $product );
|
||||
$msrp = apply_filters( 'wcj_product_msrp', get_post_meta( $product_id, '_' . 'wcj_msrp', true ), $product );
|
||||
if ( '' == $msrp || 0 == $msrp ) {
|
||||
return $price_html;
|
||||
}
|
||||
$price = $product->get_price();
|
||||
if ( ( 'show_if_diff' == $display && $msrp == $price ) || ( 'show_if_higher' == $display && $msrp <= $price ) ) {
|
||||
return $price_html;
|
||||
}
|
||||
$position = get_option( 'wcj_product_msrp_display_on_' . $section_id . '_position', 'after_price' );
|
||||
$default_template = '<div class="price"><label for="wcj_product_msrp">MSRP</label>: <span id="wcj_product_msrp"><del>%msrp%</del>%you_save%</span></div>';
|
||||
$template = apply_filters( 'booster_option', $default_template, get_option( 'wcj_product_msrp_display_on_' . $section_id . '_template', $default_template ) );
|
||||
$diff = $msrp - ( float ) $price;
|
||||
$you_save = ( $diff > 0 ? get_option( 'wcj_product_msrp_display_on_' . $section_id . '_you_save', ' (%you_save_raw%)' ) : '' );
|
||||
$you_save_percent = ( $diff > 0 ? get_option( 'wcj_product_msrp_display_on_' . $section_id . '_you_save_percent', ' (%you_save_percent_raw% %)' ) : '' );
|
||||
$you_save_round = get_option( 'wcj_product_msrp_display_on_' . $section_id . '_you_save_percent_round', 0 );
|
||||
$replaced_values = array(
|
||||
'%msrp%' => wc_price( $msrp ),
|
||||
'%you_save%' => str_replace( '%you_save_raw%', wc_price( $diff ), $you_save ),
|
||||
'%you_save_percent%' => str_replace( '%you_save_percent_raw%', round( $diff / $msrp * 100, $you_save_round ), $you_save_percent ),
|
||||
);
|
||||
return ( 'before_price' == $position ?
|
||||
wcj_handle_replacements( $replaced_values, $template ) . $price_html :
|
||||
$price_html . wcj_handle_replacements( $replaced_values, $template ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_MSRP();
|
||||
@@ -0,0 +1,400 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Open Pricing
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.4.8
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Open_Pricing' ) ) :
|
||||
|
||||
class WCJ_Product_Open_Pricing extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.5.1
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_open_pricing';
|
||||
$this->short_desc = __( 'Product Open Pricing (Name Your Price)', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Let your store customers enter price for the product manually.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-open-pricing-name-your-price';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
add_filter( WCJ_PRODUCT_GET_PRICE_FILTER, array( $this, 'get_open_price' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_product_variation_get_price',array( $this, 'get_open_price' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_get_price_html', array( $this, 'hide_original_price' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_get_variation_price_html', array( $this, 'hide_original_price' ), PHP_INT_MAX, 2 );
|
||||
if ( 'yes' === get_option( 'wcj_product_open_price_disable_quantity', 'yes' ) ) {
|
||||
add_filter( 'woocommerce_is_sold_individually', array( $this, 'hide_quantity_input_field' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
add_filter( 'woocommerce_is_purchasable', array( $this, 'is_purchasable' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_product_supports', array( $this, 'disable_add_to_cart_ajax' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_product_add_to_cart_url', array( $this, 'add_to_cart_url' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_product_add_to_cart_text', array( $this, 'add_to_cart_text' ), PHP_INT_MAX, 2 );
|
||||
$position = get_option( 'wcj_product_open_price_position', 'woocommerce_before_add_to_cart_button' );
|
||||
add_action( $position, array( $this, 'add_open_price_input_field_to_frontend' ), PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_open_price_on_add_to_cart' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_open_price_to_cart_item_data' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'woocommerce_add_cart_item', array( $this, 'add_open_price_to_cart_item' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_open_price_from_session' ), PHP_INT_MAX, 3 );
|
||||
add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_value' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
||||
if ( 'yes' === get_option( 'wcj_product_open_price_enable_loop_price_info', 'no' ) ) {
|
||||
$this->loop_price_info_template = get_option( 'wcj_product_open_price_loop_price_info_template', '<span class="price">%default_price%</span>' );
|
||||
add_action( 'woocommerce_after_shop_loop_item_title', array( $this, 'add_price_info_to_loop' ), 10 );
|
||||
}
|
||||
if ( is_admin() && 'yes' === get_option( 'wcj_product_open_price_enable_admin_product_list_column', 'no' ) ) {
|
||||
add_filter( 'manage_edit-product_columns', array( $this, 'add_product_column_open_pricing' ), PHP_INT_MAX );
|
||||
add_action( 'manage_product_posts_custom_column', array( $this, 'render_product_column_open_pricing' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_product_column_open_pricing.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function add_product_column_open_pricing( $columns ) {
|
||||
$columns['wcj_open_pricing'] = __( 'Open Pricing', 'woocommerce-jetpack' );
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* render_product_column_open_pricing.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function render_product_column_open_pricing( $column ) {
|
||||
if ( 'wcj_open_pricing' != $column ) {
|
||||
return;
|
||||
}
|
||||
if ( 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_product_open_price_enabled', true ) ) {
|
||||
echo '<span id="wcj_open_pricing_admin_column">✔</span>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_price_info_to_loop.
|
||||
*
|
||||
* @version 2.8.2
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function add_price_info_to_loop() {
|
||||
$_product_id = get_the_ID();
|
||||
if ( $this->is_open_price_product( $_product_id ) ) {
|
||||
$replaceable_values = array(
|
||||
'%default_price%' => wc_price( get_post_meta( $_product_id, '_' . 'wcj_product_open_price_default_price', true ) ),
|
||||
'%min_price%' => wc_price( get_post_meta( $_product_id, '_' . 'wcj_product_open_price_min_price', true ) ),
|
||||
'%max_price%' => wc_price( get_post_meta( $_product_id, '_' . 'wcj_product_open_price_max_price', true ) ),
|
||||
);
|
||||
echo str_replace( array_keys( $replaceable_values ), array_values( $replaceable_values ), $this->loop_price_info_template );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* is_open_price_product.
|
||||
*
|
||||
* @version 2.8.2
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function is_open_price_product( $_product ) {
|
||||
$_product_id = ( is_numeric( $_product ) ? $_product : wcj_get_product_id_or_variation_parent_id( $_product ) );
|
||||
return ( 'yes' === get_post_meta( $_product_id, '_' . 'wcj_product_open_price_enabled', true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* disable_add_to_cart_ajax.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function disable_add_to_cart_ajax( $supports, $feature, $_product ) {
|
||||
if ( $this->is_open_price_product( $_product ) && 'ajax_add_to_cart' === $feature ) {
|
||||
$supports = false;
|
||||
}
|
||||
return $supports;
|
||||
}
|
||||
|
||||
/**
|
||||
* save_meta_box_value.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function save_meta_box_value( $option_value, $option_name, $module_id ) {
|
||||
if ( true === apply_filters( 'booster_option', false, true ) ) {
|
||||
return $option_value;
|
||||
}
|
||||
if ( 'no' === $option_value ) {
|
||||
return $option_value;
|
||||
}
|
||||
if ( $this->id === $module_id && 'wcj_product_open_price_enabled' === $option_name ) {
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => 1,
|
||||
'meta_key' => '_' . 'wcj_product_open_price_enabled',
|
||||
'meta_value' => 'yes',
|
||||
'post__not_in' => array( get_the_ID() ),
|
||||
);
|
||||
$loop = new WP_Query( $args );
|
||||
$c = $loop->found_posts + 1;
|
||||
if ( $c >= 2 ) {
|
||||
add_filter( 'redirect_post_location', array( $this, 'add_notice_query_var' ), 99 );
|
||||
return 'no';
|
||||
}
|
||||
}
|
||||
return $option_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_notice_query_var.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function add_notice_query_var( $location ) {
|
||||
remove_filter( 'redirect_post_location', array( $this, 'add_notice_query_var' ), 99 );
|
||||
return add_query_arg( array( 'wcj_product_open_price_admin_notice' => true ), $location );
|
||||
}
|
||||
|
||||
/**
|
||||
* admin_notices.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function admin_notices() {
|
||||
if ( ! isset( $_GET['wcj_product_open_price_admin_notice'] ) ) {
|
||||
return;
|
||||
}
|
||||
?><div class="error"><p><?php
|
||||
echo '<div class="message">'
|
||||
. __( 'Booster: Free plugin\'s version is limited to only one open pricing product enabled at a time. You will need to get <a href="https://booster.io/plus/" target="_blank">Booster Plus</a> to add unlimited number of open pricing products.', 'woocommerce-jetpack' )
|
||||
. '</div>';
|
||||
?></p></div><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* is_purchasable.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.4.8
|
||||
* @todo maybe `wcj_get_product_id()` instead of `wcj_get_product_id_or_variation_parent_id()` - check `is_purchasable()` in `WC_Product` class.
|
||||
*/
|
||||
function is_purchasable( $purchasable, $_product ) {
|
||||
if ( $this->is_open_price_product( $_product ) ) {
|
||||
$purchasable = true;
|
||||
|
||||
// Products must exist of course
|
||||
if ( ! $_product->exists() ) {
|
||||
$purchasable = false;
|
||||
|
||||
// Other products types need a price to be set
|
||||
/* } elseif ( $_product->get_price() === '' ) {
|
||||
$purchasable = false; */
|
||||
|
||||
// Check the product is published
|
||||
} elseif ( wcj_get_product_status( $_product ) !== 'publish' && ! current_user_can( 'edit_post', wcj_get_product_id_or_variation_parent_id( $_product ) ) ) {
|
||||
$purchasable = false;
|
||||
}
|
||||
}
|
||||
return $purchasable;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_text.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function add_to_cart_text( $text, $_product ) {
|
||||
return ( $this->is_open_price_product( $_product ) ) ? __( 'Read more', 'woocommerce' ) : $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_to_cart_url.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function add_to_cart_url( $url, $_product ) {
|
||||
return ( $this->is_open_price_product( $_product ) ) ? get_permalink( wcj_get_product_id_or_variation_parent_id( $_product ) ) : $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_quantity_input_field.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function hide_quantity_input_field( $return, $_product ) {
|
||||
return ( $this->is_open_price_product( $_product ) ) ? true : $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* hide_original_price.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function hide_original_price( $price, $_product ) {
|
||||
return ( $this->is_open_price_product( $_product ) ) ? '' : $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_open_price.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function get_open_price( $price, $_product ) {
|
||||
return ( $this->is_open_price_product( $_product ) && isset( $_product->wcj_open_price ) ) ? $_product->wcj_open_price : $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* validate_open_price_on_add_to_cart.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function validate_open_price_on_add_to_cart( $passed, $product_id ) {
|
||||
$the_product = wc_get_product( $product_id );
|
||||
if ( $this->is_open_price_product( $the_product ) ) {
|
||||
$min_price = get_post_meta( $product_id, '_' . 'wcj_product_open_price_min_price', true );
|
||||
$max_price = get_post_meta( $product_id, '_' . 'wcj_product_open_price_max_price', true );
|
||||
if ( $min_price > 0 ) {
|
||||
if ( ! isset( $_POST['wcj_open_price'] ) || '' === $_POST['wcj_open_price'] ) {
|
||||
wc_add_notice( get_option( 'wcj_product_open_price_messages_required', __( 'Price is required!', 'woocommerce-jetpack' ) ), 'error' );
|
||||
return false;
|
||||
}
|
||||
if ( $_POST['wcj_open_price'] < $min_price ) {
|
||||
wc_add_notice( get_option( 'wcj_product_open_price_messages_to_small', __( 'Entered price is too small!', 'woocommerce-jetpack' ) ), 'error' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( $max_price > 0 ) {
|
||||
if ( isset( $_POST['wcj_open_price'] ) && $_POST['wcj_open_price'] > $max_price ) {
|
||||
wc_add_notice( get_option( 'wcj_product_open_price_messages_to_big', __( 'Entered price is too big!', 'woocommerce-jetpack' ) ), 'error' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $passed;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_cart_item_open_price_from_session.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function get_cart_item_open_price_from_session( $item, $values, $key ) {
|
||||
if ( array_key_exists( 'wcj_open_price', $values ) ) {
|
||||
$item['data']->wcj_open_price = $values['wcj_open_price'];
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_open_price_to_cart_item_data.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function add_open_price_to_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
|
||||
if ( isset( $_POST['wcj_open_price'] ) ) {
|
||||
$cart_item_data['wcj_open_price'] = $_POST['wcj_open_price'];
|
||||
}
|
||||
return $cart_item_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_open_price_to_cart_item.
|
||||
*
|
||||
* @version 2.4.8
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function add_open_price_to_cart_item( $cart_item_data, $cart_item_key ) {
|
||||
if ( isset( $cart_item_data['wcj_open_price'] ) ) {
|
||||
$cart_item_data['data']->wcj_open_price = $cart_item_data['wcj_open_price'];
|
||||
}
|
||||
return $cart_item_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_open_price_input_field_to_frontend.
|
||||
*
|
||||
* @version 3.7.0
|
||||
* @since 2.4.8
|
||||
*/
|
||||
function add_open_price_input_field_to_frontend() {
|
||||
if ( isset( $this->is_open_price_input_field_displayed ) ) {
|
||||
return;
|
||||
}
|
||||
$the_product = wc_get_product();
|
||||
if ( $this->is_open_price_product( $the_product ) ) {
|
||||
// Title
|
||||
$title = get_option( 'wcj_product_open_price_label_frontend', __( 'Name Your Price', 'woocommerce-jetpack' ) );
|
||||
// Prices
|
||||
$_product_id = wcj_get_product_id_or_variation_parent_id( $the_product );
|
||||
$min_price = get_post_meta( $_product_id, '_' . 'wcj_product_open_price_min_price', true );
|
||||
$max_price = get_post_meta( $_product_id, '_' . 'wcj_product_open_price_max_price', true );
|
||||
$default_price = get_post_meta( $_product_id, '_' . 'wcj_product_open_price_default_price', true );
|
||||
// Input field
|
||||
$value = ( isset( $_POST['wcj_open_price'] ) ) ? $_POST['wcj_open_price'] : $default_price;
|
||||
$default_price_step = 1 / pow( 10, absint( get_option( 'woocommerce_price_num_decimals', 2 ) ) );
|
||||
$custom_attributes = '';
|
||||
$custom_attributes .= 'step="' . get_option( 'wcj_product_open_price_price_step', $default_price_step ) . '" ';
|
||||
$custom_attributes .= ( '' == $min_price || 'no' === get_option( 'wcj_product_open_price_enable_js_validation', 'no' ) ) ? 'min="0" ' : 'min="' . $min_price . '" ';
|
||||
$custom_attributes .= ( '' == $max_price || 'no' === get_option( 'wcj_product_open_price_enable_js_validation', 'no' ) ) ? '' : 'max="' . $max_price . '" ';
|
||||
$input_field = '<input '
|
||||
. 'type="number" '
|
||||
. 'class="text" '
|
||||
. 'style="' . get_option( 'wcj_product_open_price_input_style', 'width:75px;text-align:center;' ). '" '
|
||||
. 'name="wcj_open_price" '
|
||||
. 'id="wcj_open_price" '
|
||||
. 'placeholder="' . get_option( 'wcj_product_open_price_input_placeholder', '' ) . '" '
|
||||
. 'value="' . $value . '" '
|
||||
. $custom_attributes . '>';
|
||||
// Currency symbol
|
||||
$currency_symbol = get_woocommerce_currency_symbol();
|
||||
// Replacing final values
|
||||
$replacement_values = array(
|
||||
'%frontend_label%' => $title,
|
||||
'%open_price_input%' => $input_field,
|
||||
'%currency_symbol%' => $currency_symbol,
|
||||
'%min_price_simple%' => $min_price,
|
||||
'%max_price_simple%' => $max_price,
|
||||
'%default_price_simple%' => $default_price,
|
||||
'%min_price%' => wc_price( $min_price ),
|
||||
'%max_price%' => wc_price( $max_price ),
|
||||
'%default_price%' => wc_price( $default_price ),
|
||||
);
|
||||
echo str_replace(
|
||||
array_keys( $replacement_values ),
|
||||
array_values( $replacement_values ),
|
||||
get_option( 'wcj_product_open_price_frontend_template', '<label for="wcj_open_price">%frontend_label%</label> %open_price_input% %currency_symbol%' )
|
||||
);
|
||||
$this->is_open_price_input_field_displayed = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Open_Pricing();
|
||||
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Price by Formula
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Price_by_Formula' ) ) :
|
||||
|
||||
class WCJ_Product_Price_by_Formula extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.0
|
||||
* @todo use WC math library instead of `PHPMathParser`
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_price_by_formula';
|
||||
$this->short_desc = __( 'Product Price by Formula', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Set formula for automatic product price calculation.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-product-price-formula';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
require_once( wcj_plugin_path() . '/includes/lib/PHPMathParser/Math.php' );
|
||||
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
|
||||
if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || isset( $_GET['wcj_create_products_xml'] ) ) {
|
||||
wcj_add_change_price_hooks( $this, PHP_INT_MAX - 100, false );
|
||||
}
|
||||
|
||||
add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_value' ), PHP_INT_MAX, 3 );
|
||||
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
||||
|
||||
$this->rounding = get_option( 'wcj_product_price_by_formula_rounding', 'no_rounding' );
|
||||
$this->rounding_precision = get_option( 'wcj_product_price_by_formula_rounding_precision', 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price_grouped.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function change_price_grouped( $price, $qty, $_product ) {
|
||||
if ( $_product->is_type( 'grouped' ) ) {
|
||||
foreach ( $_product->get_children() as $child_id ) {
|
||||
$the_price = get_post_meta( $child_id, '_price', true );
|
||||
$the_product = wc_get_product( $child_id );
|
||||
$the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
|
||||
if ( $the_price == $price ) {
|
||||
return $this->change_price( $price, $the_product );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* change_price.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function change_price( $price, $_product, $output_errors = false ) {
|
||||
if ( $this->is_price_by_formula_product( $_product ) && '' != $price ) {
|
||||
$_product_id = wcj_get_product_id_or_variation_parent_id( $_product );
|
||||
$is_per_product = ( 'per_product' === get_post_meta( $_product_id, '_' . 'wcj_product_price_by_formula_calculation', true ) ) ? true : false;
|
||||
$the_formula = ( $is_per_product )
|
||||
? get_post_meta( $_product_id, '_' . 'wcj_product_price_by_formula_eval', true )
|
||||
: get_option( 'wcj_product_price_by_formula_eval', '' );
|
||||
$the_formula = do_shortcode( $the_formula );
|
||||
if ( '' != $the_formula ) {
|
||||
$total_params = ( $is_per_product )
|
||||
? get_post_meta( $_product_id, '_' . 'wcj_product_price_by_formula_total_params', true )
|
||||
: get_option( 'wcj_product_price_by_formula_total_params', 1 );
|
||||
if ( $total_params > 0 ) {
|
||||
$the_current_filter = current_filter();
|
||||
if ( 'woocommerce_get_price_including_tax' == $the_current_filter || 'woocommerce_get_price_excluding_tax' == $the_current_filter ) {
|
||||
return wcj_get_product_display_price( $_product );
|
||||
}
|
||||
$math = new WCJ_Math();
|
||||
$math->registerVariable( 'x', $price );
|
||||
for ( $i = 1; $i <= $total_params; $i++ ) {
|
||||
$the_param = ( $is_per_product )
|
||||
? get_post_meta( $_product_id, '_' . 'wcj_product_price_by_formula_param_' . $i, true )
|
||||
: get_option( 'wcj_product_price_by_formula_param_' . $i, '' );
|
||||
$the_param = do_shortcode( $the_param );
|
||||
if ( '' != $the_param ) {
|
||||
$math->registerVariable( 'p' . $i, $the_param );
|
||||
}
|
||||
}
|
||||
$the_formula = str_replace( 'x', '$x', $the_formula );
|
||||
$the_formula = str_replace( 'p', '$p', $the_formula );
|
||||
try {
|
||||
$price = $math->evaluate( $the_formula );
|
||||
} catch ( Exception $e ) {
|
||||
if ( $output_errors ) {
|
||||
echo '<p style="color:red;">' . __( 'Error in formula', 'woocommerce-jetpack' ) . ': ' . $e->getMessage() . '</p>';
|
||||
}
|
||||
}
|
||||
if ( 'no_rounding' != $this->rounding ) {
|
||||
$price = wcj_round( $price, $this->rounding_precision, $this->rounding );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_variation_prices_hash.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function get_variation_prices_hash( $price_hash, $_product, $display ) {
|
||||
if ( $this->is_price_by_formula_product( $_product ) ) {
|
||||
$the_formula = get_option( 'wcj_product_price_by_formula_eval', '' );
|
||||
$total_params = get_post_meta( wcj_get_product_id_or_variation_parent_id( $_product ), '_' . 'wcj_product_price_by_formula_total_params', true );
|
||||
$the_params = array();
|
||||
for ( $i = 1; $i <= $total_params; $i++ ) {
|
||||
$the_params[] = get_option( 'wcj_product_price_by_formula_param_' . $i, '' );
|
||||
}
|
||||
$price_hash['wcj_price_by_formula'] = array(
|
||||
'formula' => $the_formula,
|
||||
'total_params' => $total_params,
|
||||
'params' => $the_params,
|
||||
'rounding' => $this->rounding,
|
||||
'rounding_precision' => $this->rounding_precision,
|
||||
);
|
||||
}
|
||||
return $price_hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* save_meta_box_value.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function save_meta_box_value( $option_value, $option_name, $module_id ) {
|
||||
if ( true === apply_filters( 'booster_option', false, true ) ) {
|
||||
return $option_value;
|
||||
}
|
||||
if ( 'no' === $option_value ) {
|
||||
return $option_value;
|
||||
}
|
||||
if ( $this->id === $module_id && 'wcj_product_price_by_formula_enabled' === $option_name ) {
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => 1,
|
||||
'meta_key' => '_' . 'wcj_product_price_by_formula_enabled',
|
||||
'meta_value' => 'yes',
|
||||
'post__not_in' => array( get_the_ID() ),
|
||||
);
|
||||
$loop = new WP_Query( $args );
|
||||
$c = $loop->found_posts + 1;
|
||||
if ( $c >= 2 ) {
|
||||
add_filter( 'redirect_post_location', array( $this, 'add_notice_query_var' ), 99 );
|
||||
return 'no';
|
||||
}
|
||||
}
|
||||
return $option_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_notice_query_var.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function add_notice_query_var( $location ) {
|
||||
remove_filter( 'redirect_post_location', array( $this, 'add_notice_query_var' ), 99 );
|
||||
return add_query_arg( array( 'wcj_product_price_by_formula_admin_notice' => true ), $location );
|
||||
}
|
||||
|
||||
/**
|
||||
* admin_notices.
|
||||
*
|
||||
* @version 2.5.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function admin_notices() {
|
||||
if ( ! isset( $_GET['wcj_product_price_by_formula_admin_notice'] ) ) {
|
||||
return;
|
||||
}
|
||||
?><div class="error"><p><?php
|
||||
echo '<div class="message">'
|
||||
. __( 'Booster: Free plugin\'s version is limited to only one price by formula product enabled at a time. You will need to get <a href="https://booster.io/plus/" target="_blank">Booster Plus</a> to add unlimited number of price by formula products.', 'woocommerce-jetpack' )
|
||||
. '</div>';
|
||||
?></p></div><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* is_price_by_formula_product.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function is_price_by_formula_product( $_product ) {
|
||||
return (
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_product_price_by_formula_enable_for_all_products', 'no' ) ) ||
|
||||
'yes' === get_post_meta( wcj_get_product_id_or_variation_parent_id( $_product ), '_' . 'wcj_product_price_by_formula_enabled', true )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_meta_box.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.5.0
|
||||
*/
|
||||
function create_meta_box() {
|
||||
|
||||
parent::create_meta_box();
|
||||
|
||||
$the_product = wc_get_product();
|
||||
if ( $this->is_price_by_formula_product( $the_product ) ) {
|
||||
$the_price = $the_product->get_price();
|
||||
$the_price = $this->change_price( $the_price, $the_product, true );
|
||||
echo '<h4>' . __( 'Final Price Preview', 'woocommerce-jetpack' ) . '</h4>';
|
||||
echo wc_price( $the_price );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Price_by_Formula();
|
||||
@@ -0,0 +1,688 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Product Tabs
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Product_Tabs' ) ) :
|
||||
|
||||
class WCJ_Product_Tabs extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @todo code refactoring and clean-up
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'product_tabs';
|
||||
$this->short_desc = __( 'Product Tabs', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add custom product tabs - globally or per product. Customize or completely remove WooCommerce default product tabs.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-custom-product-tabs';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'wp_head', array( $this, 'maybe_add_js_links' ) );
|
||||
add_filter( 'woocommerce_product_tabs', array( $this, 'customize_product_tabs' ), 98 );
|
||||
if ( 'yes' === get_option( 'wcj_custom_product_tabs_local_enabled', 'yes' ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_custom_tabs_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_custom_tabs_meta_box' ), 100, 2 );
|
||||
if ( 'yes' === get_option( 'wcj_custom_product_tabs_yoast_seo_enabled', 'no' ) ) {
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* enqueue_admin_scripts.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
*/
|
||||
function enqueue_admin_scripts() {
|
||||
if ( wcj_is_admin_product_edit_page() ) {
|
||||
wp_enqueue_script(
|
||||
'wcj-custom-tabs-yoast-seo',
|
||||
wcj_plugin_url() . '/includes/js/wcj-custom-tabs-yoast-seo.js',
|
||||
array( 'jquery', 'yoast-seo-admin-script' ),
|
||||
WCJ()->version,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_tab_key.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function get_tab_key( $tab_option_key, $scope, $product_id = 0 ) {
|
||||
$tab_key = ( 'global' === $scope ?
|
||||
get_option( 'wcj_custom_product_tabs_key_' . $tab_option_key, $tab_option_key ) :
|
||||
get_post_meta( $product_id, '_' . 'wcj_custom_product_tabs_key_' . $tab_option_key, true )
|
||||
);
|
||||
return ( '' == $tab_key ? $tab_option_key : $tab_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* customize_default_tabs.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function customize_default_tabs( $tabs ) {
|
||||
|
||||
// Unset
|
||||
if ( 'yes' === get_option( 'wcj_product_info_product_tabs_description_disable', 'no' ) ) {
|
||||
unset( $tabs['description'] );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_product_info_product_tabs_reviews_disable', 'no' ) ) {
|
||||
unset( $tabs['reviews'] );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_product_info_product_tabs_additional_information_disable', 'no' ) ) {
|
||||
unset( $tabs['additional_information'] );
|
||||
}
|
||||
|
||||
// Priority and Title
|
||||
if ( isset( $tabs['description'] ) ) {
|
||||
$tabs['description']['priority'] = apply_filters( 'booster_option', 10, get_option( 'wcj_product_info_product_tabs_description_priority', 10 ) );
|
||||
if ( '' != ( $title = get_option( 'wcj_product_info_product_tabs_description_title', '' ) ) ) {
|
||||
$tabs['description']['title'] = $title;
|
||||
}
|
||||
}
|
||||
if ( isset( $tabs['additional_information'] ) ) {
|
||||
$tabs['additional_information']['priority'] = apply_filters( 'booster_option', 20, get_option( 'wcj_product_info_product_tabs_additional_information_priority', 20 ) );
|
||||
if ( '' != ( $title = get_option( 'wcj_product_info_product_tabs_additional_information_title', '' ) ) ) {
|
||||
$tabs['additional_information']['title'] = $title;
|
||||
}
|
||||
}
|
||||
if ( isset( $tabs['reviews'] ) ) {
|
||||
$tabs['reviews']['priority'] = apply_filters( 'booster_option', 30, get_option( 'wcj_product_info_product_tabs_reviews_priority', 30 ) );
|
||||
if ( '' != ( $title = get_option( 'wcj_product_info_product_tabs_reviews_title', '' ) ) ) {
|
||||
$tabs['reviews']['title'] = $title;
|
||||
}
|
||||
}
|
||||
|
||||
// The end
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_product_tabs.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @since 3.1.0
|
||||
* @todo add visibility by user roles
|
||||
*/
|
||||
function add_custom_product_tabs( $scope, $tabs, $product_id ) {
|
||||
switch ( $scope ) {
|
||||
case 'global':
|
||||
$total_custom_tabs = apply_filters( 'booster_option', 1, get_option( 'wcj_custom_product_tabs_global_total_number', 1 ) );
|
||||
break;
|
||||
default: // 'local'
|
||||
if ( ! ( $total_custom_tabs = get_post_meta( $product_id, '_' . 'wcj_custom_product_tabs_local_total_number', true ) ) ) {
|
||||
$total_custom_tabs = apply_filters( 'booster_option', 1, get_option( 'wcj_custom_product_tabs_local_total_number_default', 1 ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
for ( $i = 1; $i <= $total_custom_tabs; $i++ ) {
|
||||
$visibility_check_function = 'is_' . $scope . '_tab_visible';
|
||||
if ( $this->$visibility_check_function( $i, $product_id ) ) {
|
||||
$option_key = $scope . '_' . $i;
|
||||
switch ( $scope ) {
|
||||
case 'global':
|
||||
$title = get_option( 'wcj_custom_product_tabs_title_' . $option_key, '' );
|
||||
$content = get_option( 'wcj_custom_product_tabs_content_' . $option_key, '' );
|
||||
$priority = get_option( 'wcj_custom_product_tabs_priority_' . $option_key, 40 );
|
||||
$link = get_option( 'wcj_custom_product_tabs_link_' . $option_key, '' );
|
||||
break;
|
||||
default: // 'local'
|
||||
$title = get_post_meta( $product_id, '_' . 'wcj_custom_product_tabs_title_' . $option_key, true );
|
||||
$content = get_post_meta( $product_id, '_' . 'wcj_custom_product_tabs_content_' . $option_key, true );
|
||||
$priority = get_post_meta( $product_id, '_' . 'wcj_custom_product_tabs_priority_' . $option_key, true );
|
||||
$link = get_post_meta( $product_id, '_' . 'wcj_custom_product_tabs_link_' . $option_key, true );
|
||||
if ( ! $priority ) {
|
||||
$priority = ( 50 + $i - 1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( '' != $title && ( '' != do_shortcode( $content ) || '' != $link ) ) {
|
||||
// Adding the tab
|
||||
$tab_key = $this->get_tab_key( $option_key, $scope, $product_id );
|
||||
$this->tab_option_keys[ $scope ][ $tab_key ] = $option_key;
|
||||
$tabs[ $tab_key ] = array(
|
||||
'title' => do_shortcode( $title ),
|
||||
'priority' => $priority,
|
||||
'callback' => array( $this, 'create_new_custom_product_tab_' . $scope ),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize the product tabs.
|
||||
*
|
||||
* @version 3.6.0
|
||||
*/
|
||||
function customize_product_tabs( $tabs ) {
|
||||
|
||||
$product_id = wcj_maybe_get_product_id_wpml( get_the_ID() );
|
||||
|
||||
// Default Tabs
|
||||
$tabs = $this->customize_default_tabs( $tabs );
|
||||
|
||||
// Custom Tabs - Global
|
||||
if ( 'yes' === get_option( 'wcj_custom_product_tabs_global_enabled', 'yes' ) ) {
|
||||
$tabs = $this->add_custom_product_tabs( 'global', $tabs, $product_id );
|
||||
}
|
||||
|
||||
// Custom Tabs - Local
|
||||
if ( 'yes' === get_option( 'wcj_custom_product_tabs_local_enabled', 'yes' ) ) {
|
||||
$tabs = $this->add_custom_product_tabs( 'local', $tabs, $product_id );
|
||||
}
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_global_tab_visible.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function is_global_tab_visible( $i, $_product_id ) {
|
||||
|
||||
// Exclude by product id
|
||||
$array_to_exclude = get_option( 'wcj_custom_product_tabs_global_hide_in_products_' . $i );
|
||||
if ( '' == $array_to_exclude || empty( $array_to_exclude ) ) {
|
||||
$list_to_exclude = get_option( 'wcj_custom_product_tabs_title_global_hide_in_product_ids_' . $i );
|
||||
if ( '' != $list_to_exclude ) {
|
||||
$array_to_exclude = explode( ',', $list_to_exclude );
|
||||
}
|
||||
}
|
||||
if ( '' != $array_to_exclude && ! empty( $array_to_exclude ) ) {
|
||||
if ( $array_to_exclude && in_array( $_product_id, $array_to_exclude ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude by product category
|
||||
$array_to_exclude = get_option( 'wcj_custom_product_tabs_global_hide_in_cats_' . $i );
|
||||
if ( '' == $array_to_exclude || empty( $array_to_exclude ) ) {
|
||||
$list_to_exclude = get_option( 'wcj_custom_product_tabs_title_global_hide_in_cats_ids_' . $i );
|
||||
if ( '' != $list_to_exclude ) {
|
||||
$array_to_exclude = explode( ',', $list_to_exclude );
|
||||
}
|
||||
}
|
||||
if ( '' != $array_to_exclude && ! empty( $array_to_exclude ) ) {
|
||||
$do_exclude = false;
|
||||
$product_categories_objects = get_the_terms( $_product_id, 'product_cat' );
|
||||
if ( $product_categories_objects && ! empty( $product_categories_objects ) ) {
|
||||
foreach ( $product_categories_objects as $product_categories_object ) {
|
||||
if ( $array_to_exclude && in_array( $product_categories_object->term_id, $array_to_exclude ) ) {
|
||||
$do_exclude = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $do_exclude ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude by product tag
|
||||
$array_to_exclude = get_option( 'wcj_custom_product_tabs_global_hide_in_tags_' . $i );
|
||||
if ( '' != $array_to_exclude && ! empty( $array_to_exclude ) ) {
|
||||
$do_exclude = false;
|
||||
$product_tags_objects = get_the_terms( $_product_id, 'product_tag' );
|
||||
if ( $product_tags_objects && ! empty( $product_tags_objects ) ) {
|
||||
foreach ( $product_tags_objects as $product_tags_object ) {
|
||||
if ( $array_to_exclude && in_array( $product_tags_object->term_id, $array_to_exclude ) ) {
|
||||
$do_exclude = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $do_exclude ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Include by product id
|
||||
$array_to_include = get_option( 'wcj_custom_product_tabs_global_show_in_products_' . $i );
|
||||
if ( '' == $array_to_include || empty( $array_to_include ) ) {
|
||||
$list_to_include = get_option( 'wcj_custom_product_tabs_title_global_show_in_product_ids_' . $i );
|
||||
if ( '' != $list_to_include ) {
|
||||
$array_to_include = explode( ',', $list_to_include );
|
||||
}
|
||||
}
|
||||
if ( '' != $array_to_include && ! empty( $array_to_include ) ) {
|
||||
// If NOT in array then hide this tab for this product
|
||||
if ( $array_to_include && ! in_array( $_product_id, $array_to_include ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Include by product category
|
||||
$array_to_include = get_option( 'wcj_custom_product_tabs_global_show_in_cats_' . $i );
|
||||
if ( '' == $array_to_include || empty( $array_to_include ) ) {
|
||||
$list_to_include = get_option( 'wcj_custom_product_tabs_title_global_show_in_cats_ids_' . $i );
|
||||
if ( '' != $list_to_include ) {
|
||||
$array_to_include = explode( ',', $list_to_include );
|
||||
}
|
||||
}
|
||||
if ( '' != $array_to_include && ! empty( $array_to_include ) ) {
|
||||
$do_include = false;
|
||||
$product_categories_objects = get_the_terms( $_product_id, 'product_cat' );
|
||||
if ( $product_categories_objects && ! empty( $product_categories_objects ) ) {
|
||||
foreach ( $product_categories_objects as $product_categories_object ) {
|
||||
if ( $array_to_include && in_array( $product_categories_object->term_id, $array_to_include ) ) {
|
||||
$do_include = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $do_include ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Include by product tag
|
||||
$array_to_include = get_option( 'wcj_custom_product_tabs_global_show_in_tags_' . $i );
|
||||
if ( '' != $array_to_include && ! empty( $array_to_include ) ) {
|
||||
$do_include = false;
|
||||
$product_tags_objects = get_the_terms( $_product_id, 'product_tag' );
|
||||
if ( $product_tags_objects && ! empty( $product_tags_objects ) ) {
|
||||
foreach ( $product_tags_objects as $product_tags_object ) {
|
||||
if ( $array_to_include && in_array( $product_tags_object->term_id, $array_to_include ) ) {
|
||||
$do_include = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $do_include ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_local_tab_visible.
|
||||
*
|
||||
* @version 2.4.7
|
||||
* @since 2.4.7
|
||||
*/
|
||||
function is_local_tab_visible( $custom_tab_index, $product_id ) {
|
||||
|
||||
// Exclude by product id
|
||||
$array_to_exclude = get_option( 'wcj_custom_product_tabs_local_hide_in_products_' . $custom_tab_index );
|
||||
if ( '' != $array_to_exclude && ! empty( $array_to_exclude ) ) {
|
||||
if ( $array_to_exclude && in_array( $product_id, $array_to_exclude ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude by product category
|
||||
$array_to_exclude = get_option( 'wcj_custom_product_tabs_local_hide_in_cats_' . $custom_tab_index );
|
||||
if ( '' != $array_to_exclude && ! empty( $array_to_exclude ) ) {
|
||||
$product_categories_objects = get_the_terms( $product_id, 'product_cat' );
|
||||
if ( $product_categories_objects && ! empty( $product_categories_objects ) ) {
|
||||
foreach ( $product_categories_objects as $product_categories_object ) {
|
||||
if ( $array_to_exclude && in_array( $product_categories_object->term_id, $array_to_exclude ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude by product tag
|
||||
$array_to_exclude = get_option( 'wcj_custom_product_tabs_local_hide_in_tags_' . $custom_tab_index );
|
||||
if ( '' != $array_to_exclude && ! empty( $array_to_exclude ) ) {
|
||||
$product_tags_objects = get_the_terms( $product_id, 'product_tag' );
|
||||
if ( $product_tags_objects && ! empty( $product_tags_objects ) ) {
|
||||
foreach ( $product_tags_objects as $product_tags_object ) {
|
||||
if ( $array_to_exclude && in_array( $product_tags_object->term_id, $array_to_exclude ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Include by product id
|
||||
$array_to_include = get_option( 'wcj_custom_product_tabs_local_show_in_products_' . $custom_tab_index );
|
||||
if ( '' != $array_to_include && ! empty( $array_to_include ) ) {
|
||||
// If NOT in array then hide this tab for this product
|
||||
if ( $array_to_include && ! in_array( $product_id, $array_to_include ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Include by product category
|
||||
$array_to_include = get_option( 'wcj_custom_product_tabs_local_show_in_cats_' . $custom_tab_index );
|
||||
if ( '' != $array_to_include && ! empty( $array_to_include ) ) {
|
||||
$do_include = false;
|
||||
$product_categories_objects = get_the_terms( $product_id, 'product_cat' );
|
||||
if ( $product_categories_objects && ! empty( $product_categories_objects ) ) {
|
||||
foreach ( $product_categories_objects as $product_categories_object ) {
|
||||
if ( $array_to_include && in_array( $product_categories_object->term_id, $array_to_include ) ) {
|
||||
$do_include = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $do_include ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Include by product tag
|
||||
$array_to_include = get_option( 'wcj_custom_product_tabs_local_show_in_tags_' . $custom_tab_index );
|
||||
if ( '' != $array_to_include && ! empty( $array_to_include ) ) {
|
||||
$do_include = false;
|
||||
$product_tags_objects = get_the_terms( $product_id, 'product_tag' );
|
||||
if ( $product_tags_objects && ! empty( $product_tags_objects ) ) {
|
||||
foreach ( $product_tags_objects as $product_tags_object ) {
|
||||
if ( $array_to_include && in_array( $product_tags_object->term_id, $array_to_include ) ) {
|
||||
$do_include = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $do_include ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_js_link_script.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function get_js_link_script( $link, $tab_key, $do_open_in_new_window ) {
|
||||
$link = do_shortcode( $link );
|
||||
$command = ( 'yes' === $do_open_in_new_window ) ?
|
||||
'window.open("' . $link . '","_blank");' :
|
||||
'window.location = "' . $link . '";';
|
||||
return '<script>' .
|
||||
'jQuery(document).ready(function() {
|
||||
jQuery("li.' . $tab_key . '_tab").click(function(){
|
||||
' . $command . '
|
||||
return false;
|
||||
});
|
||||
});' .
|
||||
'</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_add_js_links.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function maybe_add_js_links() {
|
||||
$current_post_id = wcj_maybe_get_product_id_wpml( get_the_ID() );
|
||||
// Global tabs
|
||||
for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_custom_product_tabs_global_total_number', 1 ) ); $i++ ) {
|
||||
if ( $this->is_global_tab_visible( $i, $current_post_id ) ) {
|
||||
$key = 'global_' . $i;
|
||||
if ( '' != get_option( 'wcj_custom_product_tabs_title_' . $key, '' ) && '' != ( $link = get_option( 'wcj_custom_product_tabs_link_' . $key, '' ) ) ) {
|
||||
echo $this->get_js_link_script( $link, $this->get_tab_key( $key, 'global' ), get_option( 'wcj_custom_product_tabs_link_new_tab_' . $key, true ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
// Local tabs
|
||||
if ( 'yes' !== get_option( 'wcj_custom_product_tabs_local_enabled', 'yes' ) ) {
|
||||
return;
|
||||
}
|
||||
if ( ! ( $total_custom_tabs = get_post_meta( $current_post_id, '_' . 'wcj_custom_product_tabs_local_total_number', true ) ) ) {
|
||||
$total_custom_tabs = apply_filters( 'booster_option', 1, get_option( 'wcj_custom_product_tabs_local_total_number_default', 1 ) );
|
||||
}
|
||||
for ( $i = 1; $i <= $total_custom_tabs; $i++ ) {
|
||||
if ( $this->is_local_tab_visible( $i, $current_post_id ) ) {
|
||||
$key = 'local_' . $i;
|
||||
if ( '' != get_post_meta( $current_post_id, '_' . 'wcj_custom_product_tabs_title_' . $key, true ) ) {
|
||||
if ( '' != ( $link = get_post_meta( $current_post_id, '_' . 'wcj_custom_product_tabs_link_' . $key, true ) ) ) {
|
||||
echo $this->get_js_link_script( $link, $this->get_tab_key( $key, 'local', $current_post_id ), get_post_meta( $current_post_id, '_' . 'wcj_custom_product_tabs_link_new_tab_' . $key, true ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_tab_output.
|
||||
*
|
||||
* @version 3.4.5
|
||||
* @since 3.4.5
|
||||
*/
|
||||
function get_tab_output( $content ) {
|
||||
switch ( get_option( 'wcj_custom_product_tabs_general_content_processing', 'the_content' ) ) {
|
||||
case 'disabled':
|
||||
return $content;
|
||||
case 'do_shortcode':
|
||||
return do_shortcode( $content );
|
||||
default: // case 'the_content':
|
||||
return apply_filters( 'the_content', $content );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create_new_custom_product_tab_local.
|
||||
*
|
||||
* @version 3.6.0
|
||||
*/
|
||||
function create_new_custom_product_tab_local( $key, $tab ) {
|
||||
echo $this->get_tab_output( get_post_meta( wcj_maybe_get_product_id_wpml( get_the_ID() ), '_' . 'wcj_custom_product_tabs_content_' . $this->tab_option_keys['local'][ $key ], true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* create_new_custom_product_tab_global.
|
||||
*
|
||||
* @version 3.4.5
|
||||
*/
|
||||
function create_new_custom_product_tab_global( $key, $tab ) {
|
||||
echo $this->get_tab_output( get_option( 'wcj_custom_product_tabs_content_' . $this->tab_option_keys['global'][ $key ] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* save_custom_tabs_meta_box.
|
||||
*
|
||||
* @version 3.1.0
|
||||
* @todo rewrite as standard `WCJ_Module` function
|
||||
*/
|
||||
function save_custom_tabs_meta_box( $post_id, $post ) {
|
||||
|
||||
// Check that we are saving with custom tab metabox displayed.
|
||||
if ( ! isset( $_POST['woojetpack_custom_tabs_save_post'] ) )
|
||||
return;
|
||||
|
||||
// Save: title, priority, content etc.
|
||||
$option_names = array(
|
||||
'wcj_custom_product_tabs_title_local_',
|
||||
'wcj_custom_product_tabs_key_local_',
|
||||
'wcj_custom_product_tabs_priority_local_',
|
||||
'wcj_custom_product_tabs_content_local_',
|
||||
'wcj_custom_product_tabs_link_local_',
|
||||
'wcj_custom_product_tabs_link_new_tab_local_',
|
||||
);
|
||||
$default_total_custom_tabs = apply_filters( 'booster_option', 1, get_option( 'wcj_custom_product_tabs_local_total_number_default', 1 ) );
|
||||
$total_custom_tabs_before_saving = get_post_meta( $post_id, '_' . 'wcj_custom_product_tabs_local_total_number', true );
|
||||
$total_custom_tabs_before_saving = ( '' != $total_custom_tabs_before_saving ) ? $total_custom_tabs_before_saving : $default_total_custom_tabs;
|
||||
for ( $i = 1; $i <= $total_custom_tabs_before_saving; $i++ ) {
|
||||
if ( $this->is_local_tab_visible( $i, $post_id ) ) {
|
||||
foreach ( $option_names as $option_name ) {
|
||||
update_post_meta( $post_id, '_' . $option_name . $i, $_POST[ $option_name . $i ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save: total custom tabs number
|
||||
$option_name = 'wcj_custom_product_tabs_local_total_number';
|
||||
$total_custom_tabs = isset( $_POST[ $option_name ] ) ? $_POST[ $option_name ] : $default_total_custom_tabs;
|
||||
update_post_meta( $post_id, '_' . $option_name, $_POST[ $option_name ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_tabs_meta_box.
|
||||
*
|
||||
* @version 2.4.7
|
||||
*/
|
||||
function add_custom_tabs_meta_box() {
|
||||
add_meta_box(
|
||||
'wc-jetpack-custom-tabs',
|
||||
__( 'Booster: Custom Tabs', 'woocommerce-jetpack' ),
|
||||
array( $this, 'create_custom_tabs_meta_box' ),
|
||||
'product',
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create_custom_tabs_meta_box.
|
||||
*
|
||||
* @version 3.6.0
|
||||
*/
|
||||
function create_custom_tabs_meta_box() {
|
||||
|
||||
$current_post_id = wcj_maybe_get_product_id_wpml( get_the_ID() );
|
||||
$option_name = 'wcj_custom_product_tabs_local_total_number';
|
||||
if ( ! ( $total_custom_tabs = get_post_meta( $current_post_id, '_' . $option_name, true ) ) )
|
||||
$total_custom_tabs = apply_filters( 'booster_option', 1, get_option( 'wcj_custom_product_tabs_local_total_number_default', 1 ) );
|
||||
$html = '';
|
||||
|
||||
$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 custom tabs', 'woocommerce-jetpack' );
|
||||
$html .= '</th>';
|
||||
$html .= '<td>';
|
||||
$html .= '<input type="number" min="0" id="' . $option_name . '" name="' . $option_name . '" value="' . $total_custom_tabs . '" ' . $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>';
|
||||
echo $html;
|
||||
|
||||
$options = array(
|
||||
array(
|
||||
'id' => 'wcj_custom_product_tabs_title_local_',
|
||||
'title' => __( 'Title', 'woocommerce-jetpack' ),
|
||||
'type' => 'text',
|
||||
),
|
||||
array(
|
||||
'id' => 'wcj_custom_product_tabs_key_local_',
|
||||
'title' => __( 'Key', 'woocommerce-jetpack' ),
|
||||
'type' => 'text',
|
||||
),
|
||||
array(
|
||||
'id' => 'wcj_custom_product_tabs_priority_local_',
|
||||
'title' => __( 'Order', 'woocommerce-jetpack' ),
|
||||
'type' => 'number',
|
||||
),
|
||||
array(
|
||||
'id' => 'wcj_custom_product_tabs_content_local_',
|
||||
'title' => __( 'Content', 'woocommerce-jetpack' ),
|
||||
'type' => 'textarea',
|
||||
),
|
||||
array(
|
||||
'id' => 'wcj_custom_product_tabs_link_local_',
|
||||
'title' => __( 'Link', 'woocommerce-jetpack' ),
|
||||
'type' => 'text',
|
||||
'desc_tip' => __( 'If you wish to forward tab to new link, enter it here. In this case content is ignored. Leave blank to show content.', 'woocommerce-jetpack' ),
|
||||
),
|
||||
array(
|
||||
'id' => 'wcj_custom_product_tabs_link_new_tab_local_',
|
||||
'title' => __( 'Link - Open in New Window', 'woocommerce-jetpack' ),
|
||||
'type' => 'select',
|
||||
'options' => array(
|
||||
'no' => __( 'No', 'woocommerce-jetpack' ),
|
||||
'yes' => __( 'Yes', 'woocommerce-jetpack' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
$enable_wp_editor = ( 'yes' === get_option( 'wcj_custom_product_tabs_local_wp_editor_enabled', 'yes' ) );
|
||||
for ( $i = 1; $i <= $total_custom_tabs; $i++ ) {
|
||||
$is_local_tab_visible = $this->is_local_tab_visible( $i, $current_post_id );
|
||||
$readonly = ( $is_local_tab_visible ) ? '' : ' readonly'; // not really used
|
||||
$disabled = ( $is_local_tab_visible ) ? '' : ' - ' . __( 'Disabled', 'woocommerce-jetpack' );
|
||||
$data = array();
|
||||
$html = '<hr>';
|
||||
$html .= '<h4>' . __( 'Custom Product Tab', 'woocommerce-jetpack' ) . ' #' . $i . $disabled . '</h4>';
|
||||
if ( $is_local_tab_visible ) {
|
||||
foreach ( $options as $option ) {
|
||||
$option_id = $option['id'] . $i;
|
||||
if ( ! ( $option_value = get_post_meta( $current_post_id, '_' . $option_id, true ) ) ) {
|
||||
$option_value = get_option( $option['id'] . 'default_' . $i, '' );
|
||||
if ( '' === $option_value && 'wcj_custom_product_tabs_priority_local_' === $option['id'] ) {
|
||||
$option_value = (50 + $i - 1);
|
||||
}
|
||||
if ( '' === $option_value && 'wcj_custom_product_tabs_key_local_' === $option['id'] ) {
|
||||
$option_value = 'local_' . $i;
|
||||
}
|
||||
}
|
||||
switch ( $option['type'] ) {
|
||||
case 'select':
|
||||
$the_field = '<select type="' . $option['type'] . '" id="' . $option_id . '" name="' . $option_id . '"' . $readonly . '>';
|
||||
foreach ( $option['options'] as $select_option_id => $select_option_title ) {
|
||||
$the_field .= '<option value="' . $select_option_id . '" ' . selected( $option_value, $select_option_id, false ). '>' . $select_option_title . '</option>';
|
||||
}
|
||||
$the_field .= '</select>';
|
||||
break;
|
||||
case 'number':
|
||||
$the_field = '<input style="width:25%;min-width:100px;" type="' . $option['type'] . '" id="' . $option_id . '" name="' . $option_id . '" value="' . $option_value . '"' . $readonly . '>';
|
||||
break;
|
||||
case 'text':
|
||||
$the_field = '<input style="width:50%;min-width:150px;" type="' . $option['type'] . '" id="' . $option_id . '" name="' . $option_id . '" value="' . $option_value . '"' . $readonly . '>';
|
||||
break;
|
||||
case 'textarea':
|
||||
if ( $enable_wp_editor ) {
|
||||
ob_start();
|
||||
wp_editor( $option_value, $option_id );
|
||||
$the_field = ob_get_clean();
|
||||
} else {
|
||||
$the_field = '<textarea style="width:100%;height:300px;" id="' . $option_id . '" name="' . $option_id . '"' . $readonly . '>' . $option_value . '</textarea>';
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( '' != $the_field ) {
|
||||
if ( isset( $option['desc_tip'] ) && '' != $option['desc_tip'] ) {
|
||||
$option['title'] .= '<span class="woocommerce-help-tip" data-tip="' . $option['desc_tip'] . '"></span>';
|
||||
}
|
||||
$data[] = array( $option['title'], $the_field );
|
||||
}
|
||||
}
|
||||
$html .= wcj_get_table_html( $data, array( 'table_class' => 'widefat', 'table_style' => 'margin-bottom:20px;', 'table_heading_type' => 'vertical', 'columns_styles' => array( 'width:10%;', ) ) );
|
||||
}
|
||||
echo $html;
|
||||
}
|
||||
$html = '<input type="hidden" name="woojetpack_custom_tabs_save_post" value="woojetpack_custom_tabs_save_post">';
|
||||
echo $html;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Product_Tabs();
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Products per Page
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.6.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Products_Per_Page' ) ) :
|
||||
|
||||
class WCJ_Products_Per_Page extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.6.0
|
||||
* @todo position priority for every hook
|
||||
* @todo post or get
|
||||
* @todo cookie - optional (or at least add description in admin settings)
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'products_per_page';
|
||||
$this->short_desc = __( 'Products per Page', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Add "products per page" selector to WooCommerce.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-products-per-page';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_filter( 'loop_shop_per_page', array( $this, 'set_products_per_page_number' ), PHP_INT_MAX );
|
||||
$position_hooks = get_option( 'wcj_products_per_page_position', array( 'woocommerce_before_shop_loop' ) );
|
||||
foreach ( $position_hooks as $position_hook ) {
|
||||
add_action( $position_hook, array( $this, 'add_products_per_page_form' ), get_option( 'wcj_products_per_page_position_priority', 40 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_products_per_page_form.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function add_products_per_page_form() {
|
||||
|
||||
global $wp_query;
|
||||
|
||||
if ( isset( $_REQUEST['wcj_products_per_page'] ) ) {
|
||||
$products_per_page = $_REQUEST['wcj_products_per_page'];
|
||||
} elseif ( isset( $_COOKIE['wcj_products_per_page'] ) ) {
|
||||
$products_per_page = $_COOKIE['wcj_products_per_page'];
|
||||
} else {
|
||||
$products_per_page = get_option( 'wcj_products_per_page_default', 10 ); // default
|
||||
}
|
||||
|
||||
$paged = get_query_var( 'paged' );
|
||||
if ( 0 == $paged ) {
|
||||
$paged = 1;
|
||||
}
|
||||
|
||||
$products_from = ( $paged - 1 ) * $products_per_page + 1;
|
||||
$products_to = ( $paged - 1 ) * $products_per_page + $wp_query->post_count;
|
||||
$products_total = $wp_query->found_posts;
|
||||
|
||||
$select_form = '<select name="wcj_products_per_page" id="wcj_products_per_page" class="sortby rounded_corners_class" onchange="this.form.submit()">';
|
||||
$products_per_page_select_options = apply_filters( 'booster_option',
|
||||
'10|10' . PHP_EOL . '25|25' . PHP_EOL . '50|50' . PHP_EOL . '100|100' . PHP_EOL . 'All|-1',
|
||||
get_option( 'wcj_products_per_page_select_options', '10|10' . PHP_EOL . '25|25' . PHP_EOL . '50|50' . PHP_EOL . '100|100' . PHP_EOL . 'All|-1' ) );
|
||||
$products_per_page_select_options = explode( PHP_EOL, $products_per_page_select_options );
|
||||
foreach ( $products_per_page_select_options as $products_per_page_select_option ) {
|
||||
$the_option = explode( '|', $products_per_page_select_option );
|
||||
if ( 2 === count( $the_option ) ) {
|
||||
$sort_id = $the_option[1];
|
||||
$sort_name = $the_option[0];
|
||||
$sort_id = str_replace( "\n", '', $sort_id );
|
||||
$sort_id = str_replace( "\r", '', $sort_id );
|
||||
$sort_name = str_replace( "\n", '', $sort_name );
|
||||
$sort_name = str_replace( "\r", '', $sort_name );
|
||||
$select_form .= '<option value="' . $sort_id . '" ' . selected( $products_per_page, $sort_id, false ) . ' >' . $sort_name . '</option>';
|
||||
}
|
||||
}
|
||||
$select_form .= '</select>';
|
||||
|
||||
$html = '';
|
||||
$html .= get_option( 'wcj_products_per_page_text_before', '<div class="clearfix"></div><div>' );
|
||||
$html .= '<form action="' . remove_query_arg( 'paged' ) . '" method="POST">';
|
||||
$the_text = get_option( 'wcj_products_per_page_text',
|
||||
__( 'Products <strong>%from% - %to%</strong> from <strong>%total%</strong>. Products on page %select_form%', 'woocommerce-jetpack' ) );
|
||||
$html .= str_replace( array( '%from%', '%to%', '%total%', '%select_form%' ), array( $products_from, $products_to, $products_total, $select_form ), $the_text );
|
||||
$html .= '</form>';
|
||||
$html .= get_option( 'wcj_products_per_page_text_after', '</div>' );
|
||||
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_products_per_page_number.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.5.3
|
||||
*/
|
||||
function set_products_per_page_number( $products_per_page ) {
|
||||
if ( isset( $_REQUEST['wcj_products_per_page'] ) ) {
|
||||
$products_per_page = $_REQUEST['wcj_products_per_page'];
|
||||
setcookie( 'wcj_products_per_page', $products_per_page, ( time() + 1209600 ), '/', $_SERVER['SERVER_NAME'], false );
|
||||
} elseif ( isset( $_COOKIE['wcj_products_per_page'] ) ) {
|
||||
$products_per_page = $_COOKIE['wcj_products_per_page'];
|
||||
} else {
|
||||
$products_per_page = get_option( 'wcj_products_per_page_default', 10 );
|
||||
}
|
||||
return $products_per_page;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Products_Per_Page();
|
||||
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Products XML
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.7
|
||||
* @author Algoritmika Ltd.
|
||||
* @todo create all files at once (manually and synchronize update)
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Products_XML' ) ) :
|
||||
|
||||
class WCJ_Products_XML extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'products_xml';
|
||||
$this->short_desc = __( 'Products XML Feeds', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Products XML feeds.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-products-xml-feeds';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
add_action( 'init', array( $this, 'schedule_the_events' ) );
|
||||
add_action( 'admin_init', array( $this, 'schedule_the_events' ) );
|
||||
add_action( 'admin_init', array( $this, 'wcj_create_products_xml' ) );
|
||||
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
||||
add_filter( 'cron_schedules', array( $this, 'cron_add_custom_intervals' ) );
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_products_xml_total_files', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
add_action( 'wcj_create_products_xml_hook_' . $i, array( $this, 'create_products_xml_cron' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On an early action hook, check if the hook is scheduled - if not, schedule it.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function schedule_the_events() {
|
||||
$update_intervals = array(
|
||||
'minutely',
|
||||
'hourly',
|
||||
'twicedaily',
|
||||
'daily',
|
||||
'weekly',
|
||||
);
|
||||
$total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_products_xml_total_files', 1 ) );
|
||||
for ( $i = 1; $i <= $total_number; $i++ ) {
|
||||
$event_hook = 'wcj_create_products_xml_hook_' . $i;
|
||||
if ( 'yes' === get_option( 'wcj_products_xml_enabled_' . $i, 'yes' ) ) {
|
||||
$selected_interval = apply_filters( 'booster_option', 'weekly', get_option( 'wcj_create_products_xml_period_' . $i, 'weekly' ) );
|
||||
foreach ( $update_intervals as $interval ) {
|
||||
$event_timestamp = wp_next_scheduled( $event_hook, array( $interval, $i ) );
|
||||
if ( $selected_interval === $interval ) {
|
||||
update_option( 'wcj_create_products_xml_cron_time_' . $i, $event_timestamp );
|
||||
}
|
||||
if ( ! $event_timestamp && $selected_interval === $interval ) {
|
||||
wp_schedule_event( time(), $selected_interval, $event_hook, array( $selected_interval, $i ) );
|
||||
} elseif ( $event_timestamp && $selected_interval !== $interval ) {
|
||||
wp_unschedule_event( $event_timestamp, $event_hook, array( $interval, $i ) );
|
||||
}
|
||||
}
|
||||
} else { // unschedule all events
|
||||
update_option( 'wcj_create_products_xml_cron_time_' . $i, '' );
|
||||
foreach ( $update_intervals as $interval ) {
|
||||
$event_timestamp = wp_next_scheduled( $event_hook, array( $interval, $i ) );
|
||||
if ( $event_timestamp ) {
|
||||
wp_unschedule_event( $event_timestamp, $event_hook, array( $interval, $i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cron_add_custom_intervals.
|
||||
*
|
||||
* @version 2.5.7
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function cron_add_custom_intervals( $schedules ) {
|
||||
$schedules['weekly'] = array(
|
||||
'interval' => 604800,
|
||||
'display' => __( 'Once Weekly', 'woocommerce-jetpack' )
|
||||
);
|
||||
$schedules['minutely'] = array(
|
||||
'interval' => 60,
|
||||
'display' => __( 'Once a Minute', 'woocommerce-jetpack' )
|
||||
);
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* admin_notices.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function admin_notices() {
|
||||
if ( isset( $_GET['wcj_create_products_xml_result'] ) ) {
|
||||
if ( 0 == $_GET['wcj_create_products_xml_result'] ) {
|
||||
$class = 'notice notice-error';
|
||||
$message = __( 'An error has occurred while creating products XML file.', 'woocommerce-jetpack' );
|
||||
} else {
|
||||
$class = 'notice notice-success is-dismissible';
|
||||
$message = sprintf( __( 'Products XML file #%s created successfully.', 'woocommerce-jetpack' ), $_GET['wcj_create_products_xml_result'] );
|
||||
}
|
||||
echo '<div class="' . $class . '"><p>' . $message . '</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wcj_create_products_xml.
|
||||
*
|
||||
* @version 3.3.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function wcj_create_products_xml() {
|
||||
if ( isset( $_GET['wcj_create_products_xml'] ) ) {
|
||||
$file_num = $_GET['wcj_create_products_xml'];
|
||||
$result = $this->create_products_xml( $file_num );
|
||||
if ( false !== $result ) {
|
||||
update_option( 'wcj_products_time_file_created_' . $file_num, current_time( 'timestamp' ) );
|
||||
}
|
||||
wp_safe_redirect( add_query_arg( 'wcj_create_products_xml_result', ( false === $result ? 0 : $file_num ), remove_query_arg( 'wcj_create_products_xml' ) ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create_products_xml_cron.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.5.7
|
||||
*/
|
||||
function create_products_xml_cron( $interval, $file_num ) {
|
||||
$result = $this->create_products_xml( $file_num );
|
||||
if ( false !== $result ) {
|
||||
update_option( 'wcj_products_time_file_created_' . $file_num, current_time( 'timestamp' ) );
|
||||
}
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* create_products_xml.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.5.7
|
||||
* @todo check the `str_replace` and `html_entity_decode` part
|
||||
*/
|
||||
function create_products_xml( $file_num ) {
|
||||
$xml_items = '';
|
||||
$xml_header_template = get_option( 'wcj_products_xml_header_' . $file_num, '' );
|
||||
$xml_footer_template = get_option( 'wcj_products_xml_footer_' . $file_num, '' );
|
||||
$xml_item_template = get_option( 'wcj_products_xml_item_' . $file_num, '' );
|
||||
$products_in_ids = wcj_maybe_convert_string_to_array( get_option( 'wcj_products_xml_products_incl_' . $file_num, '' ) );
|
||||
$products_ex_ids = wcj_maybe_convert_string_to_array( get_option( 'wcj_products_xml_products_excl_' . $file_num, '' ) );
|
||||
$products_cats_in_ids = get_option( 'wcj_products_xml_cats_incl_' . $file_num, '' );
|
||||
$products_cats_ex_ids = get_option( 'wcj_products_xml_cats_excl_' . $file_num, '' );
|
||||
$products_tags_in_ids = get_option( 'wcj_products_xml_tags_incl_' . $file_num, '' );
|
||||
$products_tags_ex_ids = get_option( 'wcj_products_xml_tags_excl_' . $file_num, '' );
|
||||
$products_scope = get_option( 'wcj_products_xml_scope_' . $file_num, 'all' );
|
||||
$order_by = get_option( 'wcj_products_xml_orderby_' . $file_num, 'date' );
|
||||
$order = get_option( 'wcj_products_xml_order_' . $file_num, 'DESC' );
|
||||
$max = get_option( 'wcj_products_xml_max_' . $file_num, -1 );
|
||||
$block_size = get_option( 'wcj_products_xml_block_size', 256 );
|
||||
$offset = 0;
|
||||
$counter = 0;
|
||||
while( true ) {
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => $block_size,
|
||||
'orderby' => $order_by,
|
||||
'order' => $order,
|
||||
'offset' => $offset,
|
||||
);
|
||||
if ( 'all' != $products_scope ) {
|
||||
$args['meta_query'] = WC()->query->get_meta_query();
|
||||
switch ( $products_scope ) {
|
||||
case 'sale_only':
|
||||
$args['post__in'] = array_merge( array( 0 ), wc_get_product_ids_on_sale() );
|
||||
break;
|
||||
case 'not_sale_only':
|
||||
$args['post__not_in'] = array_merge( array( 0 ), wc_get_product_ids_on_sale() );
|
||||
break;
|
||||
case 'featured_only':
|
||||
$args['post__in'] = array_merge( array( 0 ), wc_get_featured_product_ids() );
|
||||
break;
|
||||
case 'not_featured_only':
|
||||
$args['post__not_in'] = array_merge( array( 0 ), wc_get_featured_product_ids() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! empty( $products_in_ids ) ) {
|
||||
$args['post__in'] = $products_in_ids;
|
||||
}
|
||||
if ( ! empty( $products_ex_ids ) ) {
|
||||
$args['post__not_in'] = $products_ex_ids;
|
||||
}
|
||||
if ( ! empty( $products_cats_in_ids ) ) {
|
||||
if ( ! isset( $args['tax_query'] ) ) {
|
||||
$args['tax_query'] = array();
|
||||
}
|
||||
$args['tax_query'][] = array(
|
||||
'taxonomy' => 'product_cat',
|
||||
'field' => 'term_id',
|
||||
'terms' => $products_cats_in_ids,
|
||||
'operator' => 'IN',
|
||||
);
|
||||
}
|
||||
if ( ! empty( $products_cats_ex_ids ) ) {
|
||||
if ( ! isset( $args['tax_query'] ) ) {
|
||||
$args['tax_query'] = array();
|
||||
}
|
||||
$args['tax_query'][] = array(
|
||||
'taxonomy' => 'product_cat',
|
||||
'field' => 'term_id',
|
||||
'terms' => $products_cats_ex_ids,
|
||||
'operator' => 'NOT IN',
|
||||
);
|
||||
}
|
||||
if ( ! empty( $products_tags_in_ids ) ) {
|
||||
if ( ! isset( $args['tax_query'] ) ) {
|
||||
$args['tax_query'] = array();
|
||||
}
|
||||
$args['tax_query'][] = array(
|
||||
'taxonomy' => 'product_tag',
|
||||
'field' => 'term_id',
|
||||
'terms' => $products_tags_in_ids,
|
||||
'operator' => 'IN',
|
||||
);
|
||||
}
|
||||
if ( ! empty( $products_tags_ex_ids ) ) {
|
||||
if ( ! isset( $args['tax_query'] ) ) {
|
||||
$args['tax_query'] = array();
|
||||
}
|
||||
$args['tax_query'][] = array(
|
||||
'taxonomy' => 'product_tag',
|
||||
'field' => 'term_id',
|
||||
'terms' => $products_tags_ex_ids,
|
||||
'operator' => 'NOT IN',
|
||||
);
|
||||
}
|
||||
$loop = new WP_Query( $args );
|
||||
if ( ! $loop->have_posts() ) {
|
||||
break;
|
||||
}
|
||||
while ( $loop->have_posts() ) {
|
||||
if ( -1 != $max && $counter >= $max ) {
|
||||
break;
|
||||
}
|
||||
$loop->the_post();
|
||||
$xml_items .= str_replace( '&', '&', html_entity_decode( do_shortcode( $xml_item_template ) ) );
|
||||
$counter++;
|
||||
}
|
||||
$offset += $block_size;
|
||||
if ( -1 != $max && $counter >= $max ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
wp_reset_postdata();
|
||||
return file_put_contents(
|
||||
ABSPATH . get_option( 'wcj_products_xml_file_path_' . $file_num, ( ( 1 == $file_num ) ? 'products.xml' : 'products_' . $file_num . '.xml' ) ),
|
||||
do_shortcode( $xml_header_template ) . $xml_items . do_shortcode( $xml_footer_template )
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Products_XML();
|
||||
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Cost of Goods (formerly Product Cost Price)
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.2.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Purchase_Data' ) ) :
|
||||
|
||||
class WCJ_Purchase_Data extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @todo (maybe) pre-calculate profit for orders
|
||||
* @todo (maybe) "Apply costs to orders that do not have costs set"
|
||||
* @todo (maybe) "Apply costs to all orders, overriding previous costs"
|
||||
* @todo (maybe) `calculate_all_products_profit()`
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'purchase_data';
|
||||
$this->short_desc = __( 'Cost of Goods', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Save product purchase costs data for admin reports.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-cost-of-goods';
|
||||
parent::__construct();
|
||||
|
||||
$this->add_tools( array(
|
||||
'import_from_wc_cog' => array(
|
||||
'title' => __( '"WooCommerce Cost of Goods" Data Import', 'woocommerce-jetpack' ),
|
||||
'desc' => __( 'Import products costs from "WooCommerce Cost of Goods".', 'woocommerce-jetpack' ),
|
||||
),
|
||||
) );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
// Products meta boxes
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
|
||||
// Orders columns
|
||||
if (
|
||||
'yes' === get_option( 'wcj_purchase_data_custom_columns_profit', 'yes' ) ||
|
||||
'yes' === get_option( 'wcj_purchase_data_custom_columns_purchase_cost', 'no' )
|
||||
) {
|
||||
add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_order_columns' ), PHP_INT_MAX - 2 );
|
||||
add_action( 'manage_shop_order_posts_custom_column', array( $this, 'render_order_columns' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Products columns
|
||||
if (
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_purchase_data_custom_products_columns_purchase_cost', 'no' ) ) ||
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_purchase_data_custom_products_columns_profit', 'no' ) )
|
||||
) {
|
||||
add_filter( 'manage_edit-product_columns', array( $this, 'add_product_columns' ), PHP_INT_MAX );
|
||||
add_action( 'manage_product_posts_custom_column', array( $this, 'render_product_columns' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create_import_from_wc_cog_tool.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function create_import_from_wc_cog_tool() {
|
||||
// Action and Products list
|
||||
$perform_import = ( isset( $_POST['wcj_import_from_wc_cog'] ) );
|
||||
$table_data = array();
|
||||
$table_data[] = array(
|
||||
__( 'Product ID', 'woocommerce-jetpack' ),
|
||||
__( 'Product Title', 'woocommerce-jetpack' ),
|
||||
__( 'WooCommerce Cost of Goods (source)', 'woocommerce-jetpack' ),
|
||||
__( 'Booster: Product cost (destination)', 'woocommerce-jetpack' ),
|
||||
);
|
||||
foreach ( wcj_get_products( array(), 'any', 512, true ) as $product_id => $product_title ) {
|
||||
$wc_cog_cost = get_post_meta( $product_id, '_wc_cog_cost', true );
|
||||
if ( $perform_import ) {
|
||||
update_post_meta( $product_id, '_wcj_purchase_price', $wc_cog_cost );
|
||||
}
|
||||
$wcj_purchase_price = get_post_meta( $product_id, '_wcj_purchase_price', true );
|
||||
$table_data[] = array( $product_id, $product_title, $wc_cog_cost, $wcj_purchase_price );
|
||||
}
|
||||
// Button form
|
||||
$button_form = '';
|
||||
$button_form .= '<form method="post" action="">';
|
||||
$button_form .= '<input type="submit" name="wcj_import_from_wc_cog" class="button-primary" value="' . __( 'Import', 'woocommerce-jetpack' ) . '"' .
|
||||
' onclick="return confirm(\'' . __( 'Are you sure?', 'woocommerce-jetpack' ) . '\')">';
|
||||
$button_form .= '</form>';
|
||||
// Output
|
||||
$html = '';
|
||||
$html .= '<div class="wrap">';
|
||||
$html .= '<p>' . $this->get_tool_header_html( 'import_from_wc_cog' ) . '</p>';
|
||||
$html .= '<p>' . $button_form . '</p>';
|
||||
$html .= '<p>' . wcj_get_table_html( $table_data, array( 'table_heading_type' => 'horizontal', 'table_class' => 'widefat striped' ) ) . '</p>';
|
||||
$html .= '</div>';
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_product_columns.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo (maybe) output columns immediately after standard "Price"
|
||||
*/
|
||||
function add_product_columns( $columns ) {
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_purchase_data_custom_products_columns_purchase_cost', 'no' ) ) ) {
|
||||
$columns['purchase_cost'] = __( 'Cost', 'woocommerce-jetpack' );
|
||||
}
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_purchase_data_custom_products_columns_profit', 'no' ) ) ) {
|
||||
$columns['profit'] = __( 'Profit', 'woocommerce-jetpack' );
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* render_product_columns.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
* @todo variable products when `if ( 'no' === get_option( 'wcj_purchase_data_variable_as_simple_enabled', 'no' ) )`
|
||||
*/
|
||||
function render_product_columns( $column ) {
|
||||
if ( 'profit' === $column || 'purchase_cost' === $column ) {
|
||||
$product_id = get_the_ID();
|
||||
$purchase_cost = wc_get_product_purchase_price( $product_id );
|
||||
if ( 'purchase_cost' === $column ) {
|
||||
echo wc_price( $purchase_cost );
|
||||
} elseif ( 'profit' === $column ) {
|
||||
$_product = wc_get_product( $product_id );
|
||||
echo wc_price( $_product->get_price() - $purchase_cost );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_order_columns.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.2.4
|
||||
*/
|
||||
function add_order_columns( $columns ) {
|
||||
if ( 'yes' === get_option( 'wcj_purchase_data_custom_columns_profit', 'yes' ) ) {
|
||||
$columns['profit'] = __( 'Profit', 'woocommerce-jetpack' );
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_purchase_data_custom_columns_purchase_cost', 'no' ) ) {
|
||||
$columns['purchase_cost'] = __( 'Purchase Cost', 'woocommerce-jetpack' );
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output custom columns for orders
|
||||
*
|
||||
* @param string $column
|
||||
* @version 2.7.0
|
||||
* @since 2.2.4
|
||||
* @todo forecasted profit `$value = $line_total * $average_profit_margin`
|
||||
* @todo (maybe) use `[wcj_order_profit]` and `[wcj_order_items_cost]`
|
||||
*/
|
||||
function render_order_columns( $column ) {
|
||||
if ( 'profit' === $column || 'purchase_cost' === $column ) {
|
||||
$total = 0;
|
||||
$the_order = wc_get_order( get_the_ID() );
|
||||
if ( ! in_array( $the_order->get_status(), array( 'cancelled', 'refunded', 'failed' ) ) ) {
|
||||
$is_forecasted = false;
|
||||
foreach ( $the_order->get_items() as $item_id => $item ) {
|
||||
$value = 0;
|
||||
$product_id = ( isset( $item['variation_id'] ) && 0 != $item['variation_id'] && 'no' === get_option( 'wcj_purchase_data_variable_as_simple_enabled', 'no' )
|
||||
? $item['variation_id'] : $item['product_id'] );
|
||||
if ( 0 != ( $purchase_price = wc_get_product_purchase_price( $product_id ) ) ) {
|
||||
if ( 'profit' === $column ) {
|
||||
$_order_prices_include_tax = ( WCJ_IS_WC_VERSION_BELOW_3 ? $the_order->prices_include_tax : $the_order->get_prices_include_tax() );
|
||||
$line_total = ( $_order_prices_include_tax ) ? ( $item['line_total'] + $item['line_tax'] ) : $item['line_total'];
|
||||
$value = $line_total - $purchase_price * $item['qty'];
|
||||
} else { // if ( 'purchase_cost' === $column )
|
||||
$value = $purchase_price * $item['qty'];
|
||||
}
|
||||
} else {
|
||||
$is_forecasted = true;
|
||||
}
|
||||
$total += $value;
|
||||
}
|
||||
}
|
||||
if ( 0 != $total ) {
|
||||
if ( ! $is_forecasted ) {
|
||||
echo '<span style="color:green;">';
|
||||
}
|
||||
echo wc_price( $total );
|
||||
if ( ! $is_forecasted ) {
|
||||
echo '</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create_meta_box.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.4.5
|
||||
* @todo (maybe) min_profit
|
||||
*/
|
||||
function create_meta_box() {
|
||||
|
||||
parent::create_meta_box();
|
||||
|
||||
// Report
|
||||
$main_product_id = get_the_ID();
|
||||
$_product = wc_get_product( $main_product_id );
|
||||
$products = array();
|
||||
if ( $_product->is_type( 'variable' ) && 'no' === get_option( 'wcj_purchase_data_variable_as_simple_enabled', 'no' ) ) {
|
||||
$available_variations = $_product->get_available_variations();
|
||||
foreach ( $available_variations as $variation ) {
|
||||
$variation_product = wc_get_product( $variation['variation_id'] );
|
||||
$products[ $variation['variation_id'] ] = ' (' . wcj_get_product_formatted_variation( $variation_product, true ) . ')';
|
||||
}
|
||||
} else {
|
||||
$products[ $main_product_id ] = '';
|
||||
}
|
||||
foreach ( $products as $product_id => $desc ) {
|
||||
$purchase_price = wc_get_product_purchase_price( $product_id );
|
||||
if ( 0 != $purchase_price ) {
|
||||
$the_product = wc_get_product( $product_id );
|
||||
$the_price = $the_product->get_price();
|
||||
if ( 0 != $the_price ) {
|
||||
$the_profit = $the_price - $purchase_price;
|
||||
$table_data = array();
|
||||
$table_data[] = array( __( 'Selling', 'woocommerce-jetpack' ), wc_price( $the_price ) );
|
||||
$table_data[] = array( __( 'Buying', 'woocommerce-jetpack' ), wc_price( $purchase_price ) );
|
||||
$table_data[] = array( __( 'Profit', 'woocommerce-jetpack' ), wc_price( $the_profit )
|
||||
. sprintf( ' (%0.2f %%)', ( $the_profit / $purchase_price * 100 ) ) );
|
||||
$html = '';
|
||||
$html .= '<h5>' . __( 'Report', 'woocommerce-jetpack' ) . $desc . '</h5>';
|
||||
$html .= wcj_get_table_html( $table_data, array(
|
||||
'table_heading_type' => 'none',
|
||||
'table_class' => 'widefat striped',
|
||||
'table_style' => 'width:50%;min-width:300px;',
|
||||
'columns_styles' => array( 'width:33%;' ),
|
||||
) );
|
||||
echo $html;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Purchase_Data();
|
||||
@@ -0,0 +1,471 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Related Products
|
||||
*
|
||||
* @version 3.1.1
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
if ( ! class_exists( 'WCJ_Dummy_Term' ) ) {
|
||||
/**
|
||||
* WCJ_Dummy_Term class.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
class WCJ_Dummy_Term {
|
||||
public $term_id;
|
||||
function __construct() {
|
||||
$this->term_id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'WCJ_Related_Products' ) ) :
|
||||
|
||||
class WCJ_Related_Products extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.1.1
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'related_products';
|
||||
$this->short_desc = __( 'Related Products', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Change displayed related products number, columns, order; relate by tag, category, product attribute or manually on per product basis. Hide related products completely.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-related-products';
|
||||
$this->extra_desc = sprintf(
|
||||
__( 'You may need to <a class="button" href="%s">clear all products transients</a> to immediately see results on frontend after changing module\'s settings. Alternatively you can just update each product individually to clear its transients.', 'woocommerce-jetpack' ),
|
||||
add_query_arg( 'wcj_clear_all_products_transients', 'yes' )
|
||||
);
|
||||
parent::__construct();
|
||||
|
||||
// Delete Transients
|
||||
add_action( 'admin_init', array( $this, 'maybe_delete_product_transients' ), PHP_INT_MAX, 2 );
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
|
||||
// Related per Product
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_product_info_related_products_per_product', 'no' ) ) ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
if ( WCJ_IS_WC_VERSION_BELOW_3 ) {
|
||||
// Related Args
|
||||
add_filter( 'woocommerce_related_products_args', array( $this, 'related_products_args' ), PHP_INT_MAX ); // filter doesn't exist in WC3
|
||||
add_filter( 'woocommerce_output_related_products_args', array( $this, 'output_related_products_args' ), PHP_INT_MAX );
|
||||
// Fix Empty Initial Related Products Issue
|
||||
add_filter( 'woocommerce_get_related_product_tag_terms', array( $this, 'fix_empty_initial_related_products' ), PHP_INT_MAX, 2 );
|
||||
} else {
|
||||
// Related Query
|
||||
add_filter( 'woocommerce_product_related_posts_query', array( $this, 'related_products_query_wc3' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'woocommerce_product_related_posts_force_display', '__return_true', PHP_INT_MAX );
|
||||
// Related Args
|
||||
add_filter( 'woocommerce_output_related_products_args', array( $this, 'output_related_products_args_wc3' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Related Columns
|
||||
add_filter( 'woocommerce_related_products_columns', array( $this, 'related_products_columns' ), PHP_INT_MAX );
|
||||
|
||||
// Relate by Category
|
||||
if ( 'no' === get_option( 'wcj_product_info_related_products_relate_by_category', 'yes' ) ) {
|
||||
add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_false', PHP_INT_MAX );
|
||||
} else {
|
||||
add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_true', PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Relate by Tag
|
||||
if ( 'no' === get_option( 'wcj_product_info_related_products_relate_by_tag', 'yes' ) ) {
|
||||
add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_false', PHP_INT_MAX );
|
||||
} else {
|
||||
add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_true', PHP_INT_MAX );
|
||||
}
|
||||
|
||||
// Hide Related
|
||||
if ( 'yes' === get_option( 'wcj_product_info_related_products_hide', 'no' ) ) {
|
||||
add_action( ( $this->do_hide_for_all_products() ? 'init' : 'wp_head' ), array( $this, 'remove_output_related_products_action' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* do_hide_for_all_products.
|
||||
*
|
||||
* @version 3.1.1
|
||||
* @since 3.1.1
|
||||
*/
|
||||
function do_hide_for_all_products() {
|
||||
return (
|
||||
'' == get_option( 'wcj_product_info_related_products_hide_products_incl', '' ) &&
|
||||
'' == get_option( 'wcj_product_info_related_products_hide_products_excl', '' ) &&
|
||||
'' == get_option( 'wcj_product_info_related_products_hide_cats_incl', '' ) &&
|
||||
'' == get_option( 'wcj_product_info_related_products_hide_cats_excl', '' ) &&
|
||||
'' == get_option( 'wcj_product_info_related_products_hide_tags_incl', '' ) &&
|
||||
'' == get_option( 'wcj_product_info_related_products_hide_tags_excl', '' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* do_hide_for_product.
|
||||
*
|
||||
* @version 3.1.1
|
||||
* @since 3.1.1
|
||||
*/
|
||||
function do_hide_for_product( $product_id ) {
|
||||
return wcj_is_enabled_for_product( $product_id, array(
|
||||
'include_products' => get_option( 'wcj_product_info_related_products_hide_products_incl', '' ),
|
||||
'exclude_products' => get_option( 'wcj_product_info_related_products_hide_products_excl', '' ),
|
||||
'include_categories' => get_option( 'wcj_product_info_related_products_hide_cats_incl', '' ),
|
||||
'exclude_categories' => get_option( 'wcj_product_info_related_products_hide_cats_excl', '' ),
|
||||
'include_tags' => get_option( 'wcj_product_info_related_products_hide_tags_incl', '' ),
|
||||
'exclude_tags' => get_option( 'wcj_product_info_related_products_hide_tags_excl', '' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* remove_output_related_products_action.
|
||||
*
|
||||
* @version 3.1.1
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function remove_output_related_products_action( $args ) {
|
||||
if ( ! $this->do_hide_for_all_products() && ! $this->do_hide_for_product( get_the_ID() ) ) {
|
||||
return;
|
||||
}
|
||||
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20 );
|
||||
}
|
||||
|
||||
/**
|
||||
* related_products_args_wc3.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
* @todo somehow add `meta_key` in WC3 (`wc_products_array_orderby()`)
|
||||
*/
|
||||
function related_products_args_wc3( $args ) {
|
||||
// Related Num
|
||||
$args['posts_per_page'] = get_option( 'wcj_product_info_related_products_num', 3 );
|
||||
// Order By
|
||||
$args['orderby'] = get_option( 'wcj_product_info_related_products_orderby', 'rand' );
|
||||
// Order
|
||||
if ( 'rand' != $args['orderby'] ) {
|
||||
$args['order'] = get_option( 'wcj_product_info_related_products_order', 'desc' );
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* output_related_products_args_wc3.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function output_related_products_args_wc3( $args ) {
|
||||
$args['columns'] = get_option( 'wcj_product_info_related_products_columns', 3 );
|
||||
$args = $this->related_products_args_wc3( $args );
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_related_products_ids_wc3.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function get_related_products_ids_wc3( $product_id ) {
|
||||
$include_ids = array();
|
||||
// Change Related Products
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_product_info_related_products_per_product', 'no' ) ) && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true ) ) {
|
||||
// Relate per Product (Manual)
|
||||
$related_per_product = get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_ids', true );
|
||||
if ( '' != $related_per_product ) {
|
||||
$include_ids = $related_per_product;
|
||||
}
|
||||
} elseif ( 'yes' === get_option( 'wcj_product_info_related_products_by_attribute_enabled', 'no' ) ) {
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => -1,
|
||||
'orderby' => 'title',
|
||||
'order' => 'ASC',
|
||||
'fields' => 'ids',
|
||||
);
|
||||
$attribute_name = get_option( 'wcj_product_info_related_products_by_attribute_attribute_name', '' );
|
||||
$attribute_value = get_option( 'wcj_product_info_related_products_by_attribute_attribute_value', '' );
|
||||
if ( 'global' === get_option( 'wcj_product_info_related_products_by_attribute_attribute_type', 'global' ) ) {
|
||||
// Relate by Global Attributes
|
||||
// http://snippet.fm/snippets/query-for-woocommerce-products-by-global-product-attributes/
|
||||
$args['tax_query'] = array(
|
||||
array(
|
||||
'taxonomy' => 'pa_' . $attribute_name,
|
||||
'field' => 'name',
|
||||
'terms' => $attribute_value,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Relate by Local Product Attributes
|
||||
// http://snippet.fm/snippets/query-woocommerce-products-product-specific-custom-attribute/
|
||||
$serialized_value = serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value );
|
||||
// extended version: $serialized_value = serialize( $attribute_name ) . 'a:6:{' . serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value ) . serialize( 'position' );
|
||||
$args['meta_query'] = array(
|
||||
array(
|
||||
'key' => '_product_attributes',
|
||||
'value' => $serialized_value,
|
||||
'compare' => 'LIKE',
|
||||
),
|
||||
);
|
||||
}
|
||||
$loop = new WP_Query( $args );
|
||||
$include_ids = $loop->posts;
|
||||
}
|
||||
return $include_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* related_products_query_wc3.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @since 2.8.0
|
||||
* @see WC_Product_Data_Store_CPT::get_related_products_query()
|
||||
* @todo "Relate by Product Attribute" - directly to `$query['where']` instead of getting ids via `WP_Query`
|
||||
* @todo rethink hide related (for >= WC3)
|
||||
*/
|
||||
function related_products_query_wc3( $_query, $product_id ) {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Algoritmika
|
||||
if ( 'yes' === get_option( 'wcj_product_info_related_products_hide', 'no' ) ) {
|
||||
$include_ids = array( 0 );
|
||||
} else {
|
||||
$include_ids = $this->get_related_products_ids_wc3( $product_id );
|
||||
if ( empty( $include_ids ) ) {
|
||||
return $_query;
|
||||
}
|
||||
}
|
||||
$include_ids = implode( ',', array_map( 'absint', $include_ids ) );
|
||||
$cats_array = array();
|
||||
$tags_array = array();
|
||||
$_product = wc_get_product( $product_id );
|
||||
$exclude_ids = array_merge( array( 0, $product_id ), $_product->get_upsell_ids() );
|
||||
if ( 'yes' === get_option( 'wcj_product_info_related_products_hide', 'no' ) ) {
|
||||
$limit = 0;
|
||||
} else {
|
||||
$limit = get_option( 'wcj_product_info_related_products_num', 3 );
|
||||
$limit = $limit > 0 ? $limit : 5;
|
||||
$limit += 20;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
global $wpdb;
|
||||
|
||||
// Arrays to string.
|
||||
$exclude_ids = implode( ',', array_map( 'absint', $exclude_ids ) );
|
||||
$cats_array = implode( ',', array_map( 'absint', $cats_array ) );
|
||||
$tags_array = implode( ',', array_map( 'absint', $tags_array ) );
|
||||
|
||||
$limit = absint( $limit );
|
||||
$query = array();
|
||||
$query['fields'] = "SELECT DISTINCT ID FROM {$wpdb->posts} p";
|
||||
$query['join'] = " INNER JOIN {$wpdb->term_relationships} tr ON (p.ID = tr.object_id)";
|
||||
$query['join'] .= " INNER JOIN {$wpdb->term_taxonomy} tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)";
|
||||
$query['join'] .= " INNER JOIN {$wpdb->terms} t ON (t.term_id = tt.term_id)";
|
||||
$query['where'] = ' WHERE 1=1';
|
||||
$query['where'] .= " AND p.post_status = 'publish'";
|
||||
$query['where'] .= " AND p.post_type = 'product'";
|
||||
$query['where'] .= " AND p.ID NOT IN ( {$exclude_ids} )";
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Algoritmika
|
||||
if ( $include_ids ) {
|
||||
$query['where'] .= " AND p.ID IN ( {$include_ids} )";
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
$product_visibility_term_ids = wc_get_product_visibility_term_ids();
|
||||
|
||||
if ( $product_visibility_term_ids['exclude-from-catalog'] ) {
|
||||
$query['where'] .= " AND t.term_id !=" . $product_visibility_term_ids['exclude-from-catalog'];
|
||||
}
|
||||
|
||||
if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && $product_visibility_term_ids['outofstock'] ) {
|
||||
$query['where'] .= " AND t.term_id !=" . $product_visibility_term_ids['outofstock'];
|
||||
}
|
||||
|
||||
if ( $cats_array || $tags_array ) {
|
||||
$query['where'] .= ' AND (';
|
||||
|
||||
if ( $cats_array ) {
|
||||
$query['where'] .= " ( tt.taxonomy = 'product_cat' AND t.term_id IN ( {$cats_array} ) ) ";
|
||||
if ( $tags_array ) {
|
||||
$query['where'] .= ' OR ';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $tags_array ) {
|
||||
$query['where'] .= " ( tt.taxonomy = 'product_tag' AND t.term_id IN ( {$tags_array} ) ) ";
|
||||
}
|
||||
|
||||
$query['where'] .= ')';
|
||||
}
|
||||
|
||||
$query['limits'] = " LIMIT {$limit} ";
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* fix_empty_initial_related_products.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function fix_empty_initial_related_products( $terms, $product_id ) {
|
||||
$do_fix = false;
|
||||
if ( 'yes' === get_option( 'wcj_product_info_related_products_by_attribute_enabled', 'no' ) ) {
|
||||
$do_fix = true;
|
||||
} elseif (
|
||||
'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_product_info_related_products_per_product', 'no' ) ) &&
|
||||
'yes' === get_post_meta( $product_id, '_' . 'wcj_product_info_related_products_enabled', true ) &&
|
||||
'' != get_post_meta( $product_id, '_' . 'wcj_product_info_related_products_ids', true )
|
||||
) {
|
||||
$do_fix = true;
|
||||
}
|
||||
if ( $do_fix ) {
|
||||
add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_false', PHP_INT_MAX );
|
||||
add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_false', PHP_INT_MAX );
|
||||
if ( empty( $terms ) ) {
|
||||
$dummy_term = new WCJ_Dummy_Term();
|
||||
$terms[] = $dummy_term;
|
||||
}
|
||||
}
|
||||
return $terms;
|
||||
}
|
||||
|
||||
/**
|
||||
* related_products_columns.
|
||||
*
|
||||
* @version 2.6.0
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function related_products_columns( $columns ) {
|
||||
return get_option( 'wcj_product_info_related_products_columns', 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_delete_product_transients.
|
||||
*
|
||||
* @since 3.1.1
|
||||
* @version 2.6.0
|
||||
*/
|
||||
function maybe_delete_product_transients() {
|
||||
if ( isset( $_GET['wcj_clear_all_products_transients'] ) ) {
|
||||
$offset = 0;
|
||||
$block_size = 256;
|
||||
while( true ) {
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => $block_size,
|
||||
'offset' => $offset,
|
||||
'orderby' => 'title',
|
||||
'order' => 'ASC',
|
||||
'fields' => 'ids',
|
||||
);
|
||||
$loop = new WP_Query( $args );
|
||||
if ( ! $loop->have_posts() ) {
|
||||
break;
|
||||
}
|
||||
foreach ( $loop->posts as $post_id ) {
|
||||
wc_delete_product_transients( $post_id );
|
||||
}
|
||||
$offset += $block_size;
|
||||
}
|
||||
wp_safe_redirect( remove_query_arg( 'wcj_clear_all_products_transients' ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* related_products_args.
|
||||
*
|
||||
* @version 2.8.0
|
||||
* @todo save custom results as product transient (for < WC3)
|
||||
*/
|
||||
function related_products_args( $args ) {
|
||||
// Hide Related
|
||||
if ( 'yes' === get_option( 'wcj_product_info_related_products_hide', 'no' ) ) {
|
||||
return array();
|
||||
}
|
||||
// Related Num
|
||||
$args['posts_per_page'] = get_option( 'wcj_product_info_related_products_num', 3 );
|
||||
// Order By
|
||||
$orderby = get_option( 'wcj_product_info_related_products_orderby', 'rand' );
|
||||
$args['orderby'] = $orderby;
|
||||
if ( 'meta_value' === $orderby || 'meta_value_num' === $orderby ) {
|
||||
$args['meta_key'] = get_option( 'wcj_product_info_related_products_orderby_meta_value_meta_key', '' );
|
||||
}
|
||||
// Order
|
||||
if ( 'rand' != $orderby ) {
|
||||
$args['order'] = get_option( 'wcj_product_info_related_products_order', 'desc' );
|
||||
}
|
||||
// Change Related Products
|
||||
if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_product_info_related_products_per_product', 'no' ) ) && 'yes' === get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_enabled', true ) ) {
|
||||
// Relate per Product (Manual)
|
||||
$related_per_product = get_post_meta( get_the_ID(), '_' . 'wcj_product_info_related_products_ids', true );
|
||||
if ( '' != $related_per_product ) {
|
||||
$args['post__in'] = $related_per_product;
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
} elseif ( 'yes' === get_option( 'wcj_product_info_related_products_by_attribute_enabled', 'no' ) ) {
|
||||
unset( $args['post__in'] );
|
||||
$attribute_name = get_option( 'wcj_product_info_related_products_by_attribute_attribute_name', '' );
|
||||
$attribute_value = get_option( 'wcj_product_info_related_products_by_attribute_attribute_value', '' );
|
||||
if ( 'global' === get_option( 'wcj_product_info_related_products_by_attribute_attribute_type', 'global' ) ) {
|
||||
// Relate by Global Attributes
|
||||
// http://snippet.fm/snippets/query-for-woocommerce-products-by-global-product-attributes/
|
||||
$args['tax_query'] = array(
|
||||
array(
|
||||
'taxonomy' => 'pa_' . $attribute_name,
|
||||
'field' => 'name',
|
||||
'terms' => $attribute_value,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Relate by Local Product Attributes
|
||||
// http://snippet.fm/snippets/query-woocommerce-products-product-specific-custom-attribute/
|
||||
$serialized_value = serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value );
|
||||
// extended version: $serialized_value = serialize( $attribute_name ) . 'a:6:{' . serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value ) . serialize( 'position' );
|
||||
$args['meta_query'] = array(
|
||||
array(
|
||||
'key' => '_product_attributes',
|
||||
'value' => $serialized_value,
|
||||
'compare' => 'LIKE',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* output_related_products_args.
|
||||
*
|
||||
* @version 2.6.0
|
||||
*/
|
||||
function output_related_products_args( $args ) {
|
||||
$args['columns'] = get_option( 'wcj_product_info_related_products_columns', 3 );
|
||||
$args = $this->related_products_args( $args );
|
||||
return $args;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Related_Products();
|
||||
@@ -0,0 +1,307 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Reports
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Reports' ) ) :
|
||||
|
||||
class WCJ_Reports extends WCJ_Module {
|
||||
|
||||
/** @var string Report ID. */
|
||||
public $report_id;
|
||||
|
||||
/** @var int Stock reports - range in days. */
|
||||
public $range_days;
|
||||
|
||||
/** @var string: yes/no Customers reports - group countries. */
|
||||
public $group_countries;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @todo "orders report by meta" abstract class (see `WCJ_Reports_Product_Sales_Gateways`): by referer (`_wcj_track_users_http_referer`); by shipping (stored as item); by country (`_billing_country` or `_shipping_country`) etc.
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'reports';
|
||||
$this->short_desc = __( 'Reports', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Stock, sales, customers etc. reports.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-reports';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
if ( is_admin() ) {
|
||||
|
||||
add_filter( 'woocommerce_admin_reports', array( $this, 'add_customers_by_country_report' ) );
|
||||
add_filter( 'woocommerce_admin_reports', array( $this, 'add_stock_reports' ) );
|
||||
add_filter( 'woocommerce_admin_reports', array( $this, 'add_sales_reports' ) );
|
||||
add_action( 'init', array( $this, 'catch_arguments' ) );
|
||||
|
||||
include_once( 'reports/wcj-class-reports-customers.php' );
|
||||
include_once( 'reports/wcj-class-reports-stock.php' );
|
||||
include_once( 'reports/wcj-class-reports-sales-daily.php' );
|
||||
include_once( 'reports/wcj-class-reports-sales-gateways.php' );
|
||||
include_once( 'reports/wcj-class-reports-sales.php' );
|
||||
include_once( 'reports/wcj-class-reports-monthly-sales.php' );
|
||||
|
||||
add_action( 'admin_bar_menu', array( $this, 'add_custom_order_reports_ranges_to_admin_bar' ), PHP_INT_MAX );
|
||||
add_action( 'admin_bar_menu', array( $this, 'add_custom_order_reports_ranges_by_month_to_admin_bar' ), PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_order_reports_ranges_by_month_to_admin_bar.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 2.2.4
|
||||
*/
|
||||
function add_custom_order_reports_ranges_by_month_to_admin_bar( $wp_admin_bar ) {
|
||||
$is_reports = ( isset( $_GET['page'] ) && 'wc-reports' === $_GET['page'] );
|
||||
$is_orders_reports = ( isset( $_GET['tab'] ) && 'orders' === $_GET['tab'] || ! isset( $_GET['tab'] ) );
|
||||
if ( $is_reports && $is_orders_reports ) {
|
||||
|
||||
$parent = 'reports_orders_more_ranges_months';
|
||||
$args = array(
|
||||
'parent' => false,
|
||||
'id' => $parent,
|
||||
'title' => __( 'Booster: More Ranges - Months', 'woocommerce-jetpack' ),
|
||||
'href' => false,
|
||||
'meta' => array( 'title' => __( 'Select Range', 'woocommerce-jetpack' ) ),
|
||||
);
|
||||
$wp_admin_bar->add_node( $args );
|
||||
|
||||
$custom_range_nonce = wp_create_nonce( 'custom_range' );
|
||||
$current_time = (int) current_time( 'timestamp' );
|
||||
for ( $i = 1; $i <= 12; $i++ ) {
|
||||
$month_start_date = strtotime( date( 'Y-m-01', $current_time ) . " -$i months" );
|
||||
$month_num = date( 'm', $month_start_date );
|
||||
$month_name = date( 'Y F', $month_start_date );
|
||||
$start_date = date( 'Y-m-01', $month_start_date );
|
||||
$end_date = date( 'Y-m-t', $month_start_date );
|
||||
$node = array(
|
||||
'parent' => $parent,
|
||||
'id' => $parent . '_' . $month_num,
|
||||
'title' => $month_name,
|
||||
'href' => add_query_arg( array(
|
||||
'range' => 'custom',
|
||||
'start_date' => $start_date,
|
||||
'end_date' => $end_date,
|
||||
'wc_reports_nonce' => $custom_range_nonce,
|
||||
) ),
|
||||
'meta' => array( 'title' => $month_name ),
|
||||
);
|
||||
$wp_admin_bar->add_node( $node );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_custom_order_reports_ranges_to_admin_bar.
|
||||
*
|
||||
* @version 2.9.0
|
||||
*/
|
||||
function add_custom_order_reports_ranges_to_admin_bar( $wp_admin_bar ) {
|
||||
$is_reports = ( isset( $_GET['page'] ) && 'wc-reports' === $_GET['page'] );
|
||||
$is_orders_reports = ( isset( $_GET['tab'] ) && 'orders' === $_GET['tab'] || ! isset( $_GET['tab'] ) );
|
||||
if ( $is_reports && $is_orders_reports ) {
|
||||
|
||||
$parent = 'reports_orders_more_ranges';
|
||||
$args = array(
|
||||
'parent' => false,
|
||||
'id' => $parent,
|
||||
'title' => __( 'Booster: More Ranges', 'woocommerce-jetpack' ),
|
||||
'href' => false,
|
||||
'meta' => array( 'title' => __( 'Select Range', 'woocommerce-jetpack' ) ),
|
||||
);
|
||||
$wp_admin_bar->add_node( $args );
|
||||
|
||||
$custom_range_nonce = wp_create_nonce( 'custom_range' );
|
||||
foreach ( wcj_get_reports_custom_ranges() as $custom_range_id => $custom_range ) {
|
||||
$node = array(
|
||||
'parent' => $parent,
|
||||
'id' => $parent . '_' . $custom_range_id,
|
||||
'title' => $custom_range['title'],
|
||||
'href' => add_query_arg( array(
|
||||
'range' => 'custom',
|
||||
'start_date' => $custom_range['start_date'],
|
||||
'end_date' => $custom_range['end_date'],
|
||||
'wc_reports_nonce' => $custom_range_nonce,
|
||||
) ),
|
||||
'meta' => array( 'title' => $custom_range['title'] ),
|
||||
);
|
||||
$wp_admin_bar->add_node( $node );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* catch_arguments.
|
||||
*/
|
||||
function catch_arguments() {
|
||||
$this->report_id = isset( $_GET['report'] ) ? $_GET['report'] : 'on_stock';
|
||||
$this->range_days = isset( $_GET['period'] ) ? $_GET['period'] : 30;
|
||||
$this->group_countries = ( 'customers_by_country_sets' === $this->report_id ) ? 'yes' : 'no';
|
||||
}
|
||||
|
||||
/**
|
||||
* get_report_sales.
|
||||
*/
|
||||
function get_report_sales() {
|
||||
$report = new WCJ_Reports_Sales();
|
||||
echo $report->get_report();
|
||||
}
|
||||
|
||||
/**
|
||||
* get_report_products_sales_daily.
|
||||
*
|
||||
* @version 2.9.0
|
||||
* @since 2.9.0
|
||||
*/
|
||||
function get_report_products_sales_daily() {
|
||||
$report = new WCJ_Reports_Product_Sales_Daily();
|
||||
echo $report->get_report();
|
||||
}
|
||||
|
||||
/**
|
||||
* get_report_monthly_sales.
|
||||
*
|
||||
* @version 2.4.7
|
||||
* @since 2.4.7
|
||||
*/
|
||||
function get_report_monthly_sales() {
|
||||
$report = new WCJ_Reports_Monthly_Sales();
|
||||
echo $report->get_report();
|
||||
}
|
||||
|
||||
/**
|
||||
* get_report_orders_gateways.
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function get_report_orders_gateways() {
|
||||
$report = new WCJ_Reports_Product_Sales_Gateways();
|
||||
echo $report->get_report();
|
||||
}
|
||||
|
||||
/**
|
||||
* get_report_stock.
|
||||
*/
|
||||
function get_report_stock() {
|
||||
$report = new WCJ_Reports_Stock( array (
|
||||
'report_id' => $this->report_id,
|
||||
'range_days' => $this->range_days,
|
||||
) );
|
||||
echo $report->get_report_html();
|
||||
}
|
||||
|
||||
/**
|
||||
* get_report_customers.
|
||||
*/
|
||||
function get_report_customers() {
|
||||
$report = new WCJ_Reports_Customers( array ( 'group_countries' => $this->group_countries ) );
|
||||
echo $report->get_report();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add reports to WooCommerce > Reports > Sales
|
||||
*
|
||||
* @version 3.6.0
|
||||
* @since 2.3.0
|
||||
*/
|
||||
function add_sales_reports( $reports ) {
|
||||
|
||||
$reports['orders']['reports']['booster_products_sales_daily'] = array(
|
||||
'title' => __( 'Booster: Product Sales (Daily)', 'woocommerce-jetpack' ),
|
||||
'description' => '',
|
||||
'hide_title' => false,
|
||||
'callback' => array( $this, 'get_report_products_sales_daily' ),
|
||||
);
|
||||
|
||||
$reports['orders']['reports']['booster_products_sales'] = array(
|
||||
'title' => __( 'Booster: Product Sales (Monthly)', 'woocommerce-jetpack' ),
|
||||
'description' => '',
|
||||
'hide_title' => false,
|
||||
'callback' => array( $this, 'get_report_sales' ),
|
||||
);
|
||||
|
||||
$reports['orders']['reports']['booster_monthly_sales'] = array(
|
||||
'title' => __( 'Booster: Monthly Sales (with Currency Conversion)', 'woocommerce-jetpack' ),
|
||||
'description' => '',
|
||||
'hide_title' => false,
|
||||
'callback' => array( $this, 'get_report_monthly_sales' ),
|
||||
);
|
||||
|
||||
$reports['orders']['reports']['booster_gateways'] = array(
|
||||
'title' => __( 'Booster: Payment Gateways', 'woocommerce-jetpack' ),
|
||||
'description' => '',
|
||||
'hide_title' => false,
|
||||
'callback' => array( $this, 'get_report_orders_gateways' ),
|
||||
);
|
||||
|
||||
return $reports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add reports to WooCommerce > Reports > Stock
|
||||
*/
|
||||
function add_stock_reports( $reports ) {
|
||||
|
||||
$reports['stock']['reports']['on_stock'] = array(
|
||||
'title' => __( 'Booster: All in stock', 'woocommerce-jetpack' ),
|
||||
'description' => '',
|
||||
'hide_title' => true,
|
||||
'callback' => array( $this, 'get_report_stock' ),
|
||||
);
|
||||
|
||||
$reports['stock']['reports']['understocked'] = array(
|
||||
'title' => __( 'Booster: Understocked', 'woocommerce-jetpack' ),
|
||||
'description' => '',
|
||||
'hide_title' => true,
|
||||
'callback' => array( $this, 'get_report_stock' ),
|
||||
);
|
||||
|
||||
$reports['stock']['reports']['overstocked'] = array(
|
||||
'title' => __( 'Booster: Overstocked', 'woocommerce-jetpack' ),
|
||||
'description' => '',
|
||||
'hide_title' => true,
|
||||
'callback' => array( $this, 'get_report_stock' ),
|
||||
);
|
||||
|
||||
return $reports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add reports to WooCommerce > Reports > Customers
|
||||
*/
|
||||
function add_customers_by_country_report( $reports ) {
|
||||
|
||||
$reports['customers']['reports']['customers_by_country'] = array(
|
||||
'title' => __( 'Booster: Customers by Country', 'woocommerce-jetpack' ),
|
||||
'description' => '',
|
||||
'hide_title' => true,
|
||||
'callback' => array( $this, 'get_report_customers' ),
|
||||
);
|
||||
|
||||
$reports['customers']['reports']['customers_by_country_sets'] = array(
|
||||
'title' => __( 'Booster: Customers by Country Sets', 'woocommerce-jetpack' ),
|
||||
'description' => '',
|
||||
'hide_title' => true,
|
||||
'callback' => array( $this, 'get_report_customers' ),
|
||||
);
|
||||
|
||||
return $reports;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Reports();
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* Booster for WooCommerce - Module - Sale Flash
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
* @author Algoritmika Ltd.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||
|
||||
if ( ! class_exists( 'WCJ_Sale_Flash' ) ) :
|
||||
|
||||
class WCJ_Sale_Flash extends WCJ_Module {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @version 3.2.4
|
||||
* @since 3.2.4
|
||||
* @todo add predefined styles
|
||||
* @todo (maybe) per product/category/tag: separate "loop" and "single" options
|
||||
* @todo (maybe) related / homepage
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$this->id = 'sale_flash';
|
||||
$this->short_desc = __( 'Sale Flash', 'woocommerce-jetpack' );
|
||||
$this->desc = __( 'Customize products sale flash.', 'woocommerce-jetpack' );
|
||||
$this->link_slug = 'woocommerce-sale-flash';
|
||||
parent::__construct();
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
$this->globally_enabled = ( 'yes' === get_option( 'wcj_product_images_sale_flash_enabled', 'no' ) );
|
||||
$this->per_product_enabled = ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_sale_flash_per_product_enabled', 'no' ) ) );
|
||||
$this->per_category_enabled = ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_sale_flash_per_' . 'product_cat' . '_enabled', 'no' ) ) );
|
||||
$this->per_tag_enabled = ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_sale_flash_per_' . 'product_tag' . '_enabled', 'no' ) ) );
|
||||
add_filter( 'woocommerce_sale_flash', array( $this, 'customize_sale_flash' ), PHP_INT_MAX, 3 );
|
||||
if ( $this->per_product_enabled ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
|
||||
add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get_taxonomy_sale_flash.
|
||||
*
|
||||
* @version 3.2.4
|
||||
*/
|
||||
function get_taxonomy_sale_flash( $product_id, $taxonomy ) {
|
||||
$product_terms = get_the_terms( $product_id, $taxonomy );
|
||||
return ( ! empty( $product_terms ) && isset( $product_terms[0]->term_id ) ?
|
||||
do_shortcode( get_option( 'wcj_sale_flash_per_' . $taxonomy . '_' . $product_terms[0]->term_id . '_html',
|
||||
'<span class="onsale">' . __( 'Sale!', 'woocommerce' ) . '</span>' ) ) :
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* customize_sale_flash.
|
||||
*
|
||||
* @version 3.2.4
|
||||
*/
|
||||
function customize_sale_flash( $sale_flash_html, $post, $product ) {
|
||||
$product_id = wcj_get_product_id_or_variation_parent_id( $product );
|
||||
if ( $this->per_product_enabled && 'yes' === get_post_meta( $product_id, '_' . 'wcj_sale_flash_enabled', true ) ) {
|
||||
return do_shortcode( get_post_meta( $product_id, '_' . 'wcj_sale_flash', true ) );
|
||||
} elseif ( $this->per_category_enabled ) {
|
||||
if ( false !== ( $sale_flash = $this->get_taxonomy_sale_flash( $product_id, 'product_cat' ) ) ) {
|
||||
return $sale_flash;
|
||||
}
|
||||
} elseif ( $this->per_tag_enabled ) {
|
||||
if ( false !== ( $sale_flash = $this->get_taxonomy_sale_flash( $product_id, 'product_tag' ) ) ) {
|
||||
return $sale_flash;
|
||||
}
|
||||
} elseif ( $this->globally_enabled ) {
|
||||
// Hiding
|
||||
if ( 'yes' === get_option( 'wcj_product_images_sale_flash_hide_everywhere', 'no' ) ) {
|
||||
return '';
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_product_images_sale_flash_hide_on_archives', 'no' ) && is_archive() ) {
|
||||
return '';
|
||||
}
|
||||
if ( 'yes' === get_option( 'wcj_product_images_sale_flash_hide_on_single', 'no' ) && is_single() && get_the_ID() === $product_id ) {
|
||||
return '';
|
||||
}
|
||||
// Content
|
||||
return do_shortcode( get_option( 'wcj_product_images_sale_flash_html', '<span class="onsale">' . __( 'Sale!', 'woocommerce' ) . '</span>' ) );
|
||||
}
|
||||
return $sale_flash_html;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
return new WCJ_Sale_Flash();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user