first commit

This commit is contained in:
2026-03-05 13:07:40 +01:00
commit 64ba0721ee
25709 changed files with 4691006 additions and 0 deletions

View File

@@ -0,0 +1,170 @@
<?php
defined( 'ABSPATH' ) || exit;
class WPMultiStepCheckout_Settings {
/**
* Constructor
*/
public function __construct() {
require_once 'settings-array.php';
require_once 'frm/class-form-fields.php';
require_once 'frm/premium-tooltips.php';
require_once 'frm/warnings.php';
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
add_action( 'admin_enqueue_scripts', array($this, 'admin_enqueue_scripts') );
$this->warnings();
}
/**
* Create the menu link
*/
function admin_menu() {
add_submenu_page(
'woocommerce',
'Multi-Step Checkout',
'Multi-Step Checkout',
'manage_options',
'wmsc-settings',
array($this, 'admin_settings_page')
);
}
/**
* Enqueue the scripts and styles
*/
function admin_enqueue_scripts() {
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_URL);
if ( $page != 'wmsc-settings' ) return false;
// Color picker
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script('wp-color-picker');
$u = plugins_url('/', WMSC_PLUGIN_FILE) . 'assets/'; // assets url
$f = plugins_url('/', WMSC_PLUGIN_FILE) . 'includes/frm/assets/'; // framework assets url
$v = WMSC_VERSION; // version
$d = array('jquery'); // dependency
$w = true; // where? in the footer?
// Load scripts
wp_enqueue_script( 'wmsc-bootstrap', $f.'bootstrap.min.js', $d, $v, $w);
wp_enqueue_script( 'wmsc-admin-script', $u.'js/admin-script.js', $d, $v, $w);
// Load styles
wp_enqueue_style ( 'wmsc-bootstrap', $f.'bootstrap.min.css', array(), $v);
wp_enqueue_style ( 'wmsc-admin-style', $u.'css/admin-style.css', array(), $v);
}
/**
* Output the admin page
* @access public
*/
public function admin_settings_page() {
// Get the tabs.
$tabs = array(
'general' => __('General Settings', 'wp-multi-step-checkout'),
'design' => __('Design', 'wp-multi-step-checkout'),
'titles' => __('Text on Steps and Buttons', 'wp-multi-step-checkout')
);
$tab_current = (isset($_GET['tab'])) ? $_GET['tab'] : 'general';
if ( ! isset( $tabs[ $tab_current ] ) ) $tab_current = 'general';
// Get the field settings.
$settings_all = get_wmsc_settings();
$values_current = get_option( 'wmsc_options', array() );
$form = new \SilkyPressFrm\Form_Fields( $settings_all );
$form->add_setting( 'tooltip_img', plugins_url('/', WMSC_PLUGIN_FILE) . 'assets/images/question_mark.svg' );
$form->add_setting( 'section', $tab_current );
$form->add_setting( 'label_class', 'col-sm-5' );
$form->set_current_values( $values_current );
// The settings were saved.
if ( ! empty( $_POST ) ) {
check_admin_referer( 'wmsc_' . $tab_current );
if ( current_user_can( 'manage_woocommerce' ) ) {
$values_post_sanitized = $form->validate( $_POST );
$form->set_current_values( $values_post_sanitized );
foreach ( $settings_all as $_key => $_setting ) {
if ( isset( $_setting['pro'] ) && $_setting['pro'] && isset( $_setting['value'] ) ) {
$values_post_sanitized[ $_key ] = $_setting['value'];
}
}
if ( update_option( 'wmsc_options', $values_post_sanitized ) ) {
$form->add_message( 'success', '<b>'. __('Your settings have been saved.') . '</b>' );
}
}
}
// Premium tooltips.
$message = __('Only available in <a href="%1$s" target="_blank">PRO version</a>', 'wp-multi-step-checkout');
$message = wp_kses( $message, array('a' => array('href' => array(), 'target'=> array())));
$message = sprintf( $message, 'https://www.silkypress.com/woocommerce-multi-step-checkout-pro/?utm_source=wordpress&utm_campaign=wmsc_free&utm_medium=banner');
new SilkyPress_PremiumTooltips($message);
// Render the content.
$messages = $form->render_messages();
$content = $form->render();
include_once 'admin-template.php';
include_once 'right_columns.php';
}
/**
* Show admin warnings
*/
function warnings() {
$allowed_actions = array(
'wmsc_dismiss_suki_theme',
'wmsc_dismiss_german_market_hooks',
'wmsc_dismiss_elementor_pro_widget',
);
$w = new SilkyPress_Warnings($allowed_actions);
if ( !$w->is_url('plugins') && !$w->is_url('wmsc-settings') ) {
return;
}
// Warning about the Suki theme
if ( strpos( strtolower(get_template()), 'suki') !== false && $w->is_url('wmsc-settings') ) {
$message = __('The Suki theme adds some HTML elements to the checkout page in order to create the two columns. This additional HTML messes up the steps from the multi-step checkout plugin. Unfortunately the multi-step checkout plugin isn\'t compatibile with the Suki theme.', 'wp-multi-step-checkout');
$w->add_notice( 'wmsc_dismiss_suki_theme', $message);
}
// Warning if the hooks from the German Market plugin are turned on
if ( class_exists('Woocommerce_German_Market') && get_option( 'gm_deactivate_checkout_hooks', 'off' ) != 'off' && $w->is_url('wmsc-settings') ) {
$message = __('The "Deactivate German Market Hooks" option on the <b>WP Admin -> WooCommerce -> German Market -> Ordering</b> page will interfere with the proper working of the <b>Multi-Step Checkout for WooCommerce</b> plugin. Please consider turning the option off.', 'wp-multi-step-checkout');
$w->add_notice( 'wmsc_dismiss_german_market_hooks', $message);
}
// Warning about the Elementor Pro Checkout widget.
if ( defined( 'ELEMENTOR_PRO_VERSION' ) ) {
$message = __('If the Elementor Pro Checkout widget is used on the checkout page, make sure the "Skin" option is set to "Multi-Step Checkout" in the widget\'s "Content -> General" section.', 'wp-multi-step-checkout');
$w->add_notice( 'wmsc_dismiss_elementor_pro_widget', $message);
}
$w->show_warnings();
}
}
new WPMultiStepCheckout_Settings();

View File

@@ -0,0 +1,49 @@
<?php
/**
* Admin settings page
*/
defined( 'ABSPATH' ) || exit;
?>
<h2>Multi-Step Checkout for WooCommerce by <img src="<?php echo plugins_url('/', WMSC_PLUGIN_FILE); ?>assets/images/silkypress_logo.png" /> <a href="https://www.silkypress.com/" target="_blank">SilkyPress</a></h2>
<div class="wrap">
<h3 class="nav-tab-wrapper woo-nav-tab-wrapper">
<?php foreach ( $tabs as $_key => $_val ) : ?>
<?php $active = ( $_key == $tab_current ) ? ' nav-tab-active' : ''; ?>
<a href="?page=wmsc-settings&tab=<?php echo $_key ?>" class="nav-tab<?php echo $active; ?>"><?php _e($_val); ?></a>
<?php endforeach; ?>
</h3>
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
<div id="alert_messages">
<?php echo $messages; ?>
</div>
<?php if( isset($without_form) && $without_form == true ) : ?>
<div class="form-group">
<?php echo $content; ?>
</div>
<?php else : ?>
<form class="form-horizontal" method="post" action="" id="form_settings">
<div class="form-group">
<?php echo $content; ?>
<div class="form-group">
<div class="col-lg-6">
<button type="submit" class="btn btn-primary"><?php echo __('Save changes'); ?></button>
</div>
</div>
</div>
<?php wp_nonce_field( 'wmsc_' . $tab_current ); ?>
</form>
<?php endif; ?>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,57 @@
<?php
defined( 'ABSPATH' ) || exit;
use ElementorPro\Plugin;
use ElementorPro\Modules\Woocommerce\Widgets\Checkout;
use Elementor\Widget_Base;
use Elementor\Skin_Base;
use Elementor\Controls_Manager;
class WMSC_Multistep_Checkout_Skin extends Skin_Base {
public function __construct( Widget_Base $parent ) {
$this->parent = $parent;
}
public function get_id() {
return 'multistep-checkout';
}
public function get_title() {
return __( 'Multi-Step Checkout', 'wp-multi-step-checkout' );
}
public function render() {
$is_editor = Plugin::elementor()->editor->is_edit_mode();
if ( $is_editor ) {
$store_current_user = wp_get_current_user()->ID;
wp_set_current_user( 0 );
}
$this->add_render_hooks_multistep();
echo do_shortcode( '[woocommerce_checkout]' );
$this->parent->remove_render_hooks();
if ( $is_editor ) {
wp_set_current_user( $store_current_user );
}
}
public function add_render_hooks_multistep() {
add_filter( 'woocommerce_form_field_args', array( $this->parent, 'modify_form_field' ), 70, 3 );
add_filter( 'woocommerce_get_terms_and_conditions_checkbox_text', array( $this->parent, 'woocommerce_terms_and_conditions_checkbox_text' ), 10, 1 );
add_filter( 'gettext', array( $this->parent, 'filter_gettext' ), 20, 3 );
// add_action( 'woocommerce_checkout_before_order_review_heading', array( $this->parent, 'woocommerce_checkout_before_order_review_heading_1' ), 5 );
// add_action( 'woocommerce_checkout_before_order_review_heading', array( $this->parent, 'woocommerce_checkout_before_order_review_heading_2' ), 95 );
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_login_form' );
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* The buttons under the steps
*
* @package WPMultiStepCheckout
*/
defined( 'ABSPATH' ) || exit;
$buttons_class = apply_filters( 'wmsc_buttons_class', 'button alt' );
$wrapper_class = apply_filters( 'wmsc_buttons_wrapper_class', 'wpmc-nav-wrapper' );
$back_to_cart = ( isset( $options['show_back_to_cart_button'] ) && $options['show_back_to_cart_button'] ) ? true : false;
if ( ! $back_to_cart ) {
$wrapper_class .= ' wpmc-no-back-to-cart';
}
?>
<!-- The steps buttons -->
<div class="<?php echo $wrapper_class; // phpcs:ignore ?>">
<?php if ( $back_to_cart ) : ?>
<button data-href="<?php echo wc_get_cart_url(); ?>" id="wpmc-back-to-cart" class="<?php echo $buttons_class; // phpcs:ignore ?>" type="button"><?php echo $options['t_back_to_cart']; // phpcs:ignore ?></button>
<?php endif; ?>
<button id="wpmc-prev" class="<?php echo $buttons_class; // phpcs:ignore ?> button-inactive wpmc-nav-button" type="button"><?php echo $options['t_previous']; // phpcs:ignore ?></button>
<?php if ( $show_login_step ) : ?>
<button id="wpmc-next" class="<?php echo $buttons_class; // phpcs:ignore ?> button-active wpmc-nav-button" type="button"><?php echo $options['t_next']; // phpcs:ignore ?></button>
<button id="wpmc-skip-login" class="<?php echo $buttons_class; // phpcs:ignore ?> button-active current wpmc-nav-button" type="button"><?php echo $options['t_skip_login']; // phpcs:ignore ?></button>
<?php else : ?>
<button id="wpmc-next" class="<?php echo $buttons_class; // phpcs:ignore ?> button-active current wpmc-nav-button" type="button"><?php echo $options['t_next']; // phpcs:ignore ?></button>
<?php endif; ?>
</div>
<div style="clear: both;"></div>

View File

@@ -0,0 +1,168 @@
<?php
/**
* Checkout Form
*
* This is an overridden copy of the woocommerce/templates/checkout/form-checkout.php file.
*
* @package WPMultiStepCheckout
*/
defined( 'ABSPATH' ) || exit;
// check the WooCommerce MultiStep Checkout options
$options = get_option('wmsc_options');
require_once 'settings-array.php';
if ( !is_array($options) || count($options) === 0 ) {
$defaults = get_wmsc_settings();
$options = array();
foreach($defaults as $_key => $_value ) {
$options[$_key] = $_value['value'];
}
}
$options = array_map('stripslashes', $options);
// Use the WPML values instead of the ones from the admin form
if ( isset($options['t_wpml']) && $options['t_wpml'] == 1 ) {
$defaults = get_wmsc_settings();
foreach($options as $_key => $_value ) {
if( substr($_key, 0, 2) == 't_' && $_key != 't_sign') {
$options[$_key] = $defaults[$_key]['value'];
}
}
}
if ( !isset($options['c_sign']) ) $options['c_sign'] = '&';
// Get the steps
$steps = get_wmsc_steps();
// Set the step titles
$steps['billing']['title'] = $options['t_billing'];
$steps['shipping']['title'] = $options['t_shipping'];
$steps['review']['title'] = $options['t_order'];
$steps['payment']['title'] = $options['t_payment'];
// check the WooCommerce options
$is_registration_enabled = version_compare('3.0', WC()->version, '<=') ? $checkout->is_registration_enabled() : get_option( 'woocommerce_enable_signup_and_login_from_checkout' ) == 'yes';
$has_checkout_fields = version_compare('3.0', WC()->version, '<=') ? $checkout->get_checkout_fields() : (is_array($checkout->checkout_fields) && count($checkout->checkout_fields) > 0 );
$show_login_step = ( is_user_logged_in() || 'no' === get_option( 'woocommerce_enable_checkout_login_reminder' ) ) ? false : true;
$stop_at_login = ( ! $is_registration_enabled && $checkout->is_registration_required() && ! is_user_logged_in() ) ? true : false;
$checkout_url = apply_filters( 'woocommerce_get_checkout_url', version_compare( '2.5', WC()->version, '<=' ) ? wc_get_checkout_url() : WC()->cart->get_checkout_url() );
// Both options disabled for "Guest" on the WP Admin -> WooCommerce -> Settings -> Accounts & Privacy page
if ( ! $is_registration_enabled && $checkout->is_registration_required() && ! is_user_logged_in() && ! $show_login_step) {
echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', __( 'You must be logged in to checkout.', 'woocommerce' ) ) );
return;
}
// Swap the Payment and Review steps for german shops
$swap_payment_review = ( class_exists('WooCommerce_Germanized') || class_exists('Woocommerce_German_Market')) ? true : false;
$swap_payment_review = apply_filters('wpmc_swap_payment_review', $swap_payment_review);
if ( $swap_payment_review ) {
$tmp = $steps['payment']['position'];
$steps['payment']['position'] = $steps['review']['position'];
$steps['review']['position'] = $tmp;
}
// Disabled "Show the Shipping step" option on Multi-Step Checkout -> General Settings page
if ( !$options['show_shipping_step'] ) {
unset($steps['shipping']);
$options['unite_billing_shipping'] = false;
$steps['billing']['sections'][] = 'woocommerce_checkout_after_customer_details';
}
// Enabled "Show the Order and the Payment steps together" option on Multi-Step Checkout -> General Settings page
if ( $options['unite_order_payment']) {
$steps['review']['title'] = $options['t_order'] . ' '.esc_html($options['c_sign']).' ' . $options['t_payment'];
$steps['review']['class'] = $steps['review']['class'] . ' ' . $steps['payment']['class'];
$steps['review']['sections'] = array('review', 'payment');
if ( $swap_payment_review ) {
$steps['review']['sections'] = array('payment', 'review');
}
unset($steps['payment']);
}
// Enabled "Show the Order and the Payment steps together" option on Multi-Step Checkout -> General Settings page
if ( $options['unite_billing_shipping'] && $options['show_shipping_step'] ) {
$steps['billing']['title'] = $options['t_billing'] . ' '.esc_html($options['c_sign']).' ' . $options['t_shipping'];
$steps['billing']['class'] = $steps['billing']['class'] . ' ' . $steps['shipping']['class'];
$steps['billing']['sections'] = array('billing', 'shipping');
unset($steps['shipping']);
}
// No checkout fields within the $checkout object
if ( !$has_checkout_fields) {
unset($steps['billing']);
unset($steps['shipping']);
}
// Pass the steps through a filter
$steps = apply_filters('wpmc_modify_steps', $steps);
// Sort the steps
uasort($steps, 'wpmc_sort_by_position');
// show the tabs
include dirname(__FILE__) . '/form-tabs.php';
do_action( 'wpmc_after_step_tabs' );
?>
<div style="clear: both;"></div>
<?php wc_print_notices(); ?>
<div style="clear: both;"></div>
<div class="wpmc-steps-wrapper">
<div id="checkout_coupon" class="woocommerce_checkout_coupon" style="display: none;">
<?php do_action( 'wpmc-woocommerce_checkout_coupon_form', $checkout ); ?>
</div>
<div id="woocommerce_before_checkout_form" class="woocommerce_before_checkout_form" data-step="<?php echo apply_filters('woocommerce_before_checkout_form_step', 'step-review'); ?>" style="display: none;">
<?php do_action( 'woocommerce_before_checkout_form', $checkout ); ?>
</div>
<!-- Step: Login -->
<?php
if ( $show_login_step ) {
wmsc_step_content_login($checkout, $stop_at_login);
}
if ( $stop_at_login ) {
echo '</div>'; // closes the "wpmc-steps-wrapper" div
return false;
}
?>
<form name="checkout" method="post" class="checkout woocommerce-checkout" action="<?php echo esc_url( $checkout_url ); ?>" enctype="multipart/form-data">
<?php $first_step = ( $show_login_step ) ? '' : ' current';
foreach( $steps as $_id => $_step ) {
echo '<!-- Step: '.$_step['title'].' -->';
echo '<div class="wpmc-step-item '.$_step['class']. $first_step . '">';
if ( isset($_step['sections'] ) ) {
foreach ( $_step['sections'] as $_section ) {
if ( strpos($_section, 'woocommerce_') === 0 ) {
do_action( $_section );
} else {
do_action('wmsc_step_content_' . $_section);
}
}
} else {
do_action('wmsc_step_content_' . $_id);
}
echo '</div>';
$first_step = '';
} ?>
</form>
<?php do_action( 'woocommerce_after_checkout_form', $checkout ); ?>
</div>
<?php include dirname(__FILE__) . '/form-buttons.php'; ?>

View File

@@ -0,0 +1,37 @@
<?php
/**
* The steps tabs
*
* @package WPMultiStepCheckout
*/
defined( 'ABSPATH' ) || exit;
$i = 0;
$number_of_steps = ( $show_login_step ) ? count( $steps ) + 1 : count( $steps );
$current_step_title = ( $show_login_step ) ? 'login' : key( array_slice( $steps, 0, 1, true ) );
do_action( 'wpmc_before_tabs' );
?>
<!-- The steps tabs -->
<div class="wpmc-tabs-wrapper">
<ul class="wpmc-tabs-list wpmc-<?php echo $number_of_steps; ?>-tabs" data-current-title="<?php echo $current_step_title; ?>">
<?php if ( $show_login_step ) : ?>
<li class="wpmc-tab-item current wpmc-login" data-step-title="login">
<div class="wpmc-tab-number"><?php echo $i = $i + 1; ?></div>
<div class="wpmc-tab-text"><?php echo $options['t_login']; ?></div>
</li>
<?php endif; ?>
<?php
foreach ( $steps as $_id => $_step ) :
$class = ( ! $show_login_step && $i == 0 ) ? ' current' : '';
?>
<li class="wpmc-tab-item<?php echo $class; ?> wpmc-<?php echo $_id; ?>" data-step-title="<?php echo $_id; ?>">
<div class="wpmc-tab-number"><?php echo $i = $i + 1; ?></div>
<div class="wpmc-tab-text"><?php echo $_step['title']; ?></div>
</li>
<?php endforeach; ?>
</ul>
</div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,362 @@
<?php
/**
* Form_Fields. Render form fields out of an array.
*
* @class Form_Fields
* @package SilkyPressFrm
*/
namespace SilkyPressFrm;
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( '\SilkyPressFrm\Form_Fields' ) ) {
/**
* Form_Fields class.
*/
class Form_Fields {
/**
* Fields description.
*
* @var array
*/
private $fields = array();
/**
* Current field values.
*
* @var array
*/
private $current_values = array();
/**
* Additional attributes.
*
* @var array
*/
private $atts = array();
/**
* Validation error/info messages.
*
* @var array
*/
private $messages = array();
/**
* Constructor.
*
* @param array $fields The field description array.
*/
public function __construct( $fields = array() ) {
$this->fields = $fields;
// Default attributes.
$this->atts = array(
'tooltip_img' => '',
'section' => '',
'label-class' => '',
'disable_pro' => true,
);
}
/**
* Add settings.
*
* @param string $var Variable.
* @param string $value Value.
*/
public function add_setting( $var = '', $value = '' ) {
$this->atts[ $var ] = $value;
}
/**
* Set the $this->current_values array.
*
* @param array $values Current values.
*/
public function set_current_values( $values = array() ) {
$this->current_values = $values;
}
/**
* Render all the fields.
*
* @param array $fields The fields to be rendered.
*
* @return string The rendered fields.
*/
public function render( $fields = null ) {
$content = '';
$fields = ( null === $fields ) ? $this->fields : array();
if ( count( $fields ) === 0 ) {
return '';
}
foreach ( $fields as $_key => $_field ) {
if ( isset( $this->atts['section'] ) && $_field['section'] !== $this->atts['section'] ) {
continue;
}
$content .= $this->render_field( $_key, $_field );
}
return $content;
}
/**
* Render one field
*
* @param string $_key The field's id.
* @param array $_field The fields' description.
*
* @return string The rendered field.
*/
public function render_field( $_key, $_field ) {
$atts = '';
$description = '';
$label = '';
$input_values = '';
$add_label = true;
$group_wrap = true;
if ( 'header' === $_field['input_form'] || isset( $_field['no_wrap'] ) ) {
$add_label = true;
$group_wrap = false;
}
$_field['value'] = isset( $this->current_values[ $_key ] ) ? $this->current_values[ $_key ] : $_field['value'];
$_field['disabled'] = ( $this->atts['disable_pro'] && isset( $_field['pro'] ) && $_field['pro'] ) ? true : false;
$atts .= ( isset( $_field['disabled'] ) && $_field['disabled'] ) ? ' disabled' : '';
$atts .= ( 'checkbox' === $_field['input_form'] && true === (bool) $_field['value'] && ! $_field['disabled'] ) ? ' checked="checked"' : '';
// Radio templates.
if ( 'radio' === $_field['input_form'] ) {
foreach ( $_field['values'] as $__id => $__value ) {
$_style = isset( $_field['style'] ) && 'inline' === $_field['style'] ? '-inline' : '';
$input_atts = ( $__id === $_field['value'] ) ? $atts . ' checked=""' : $atts;
$input_values .= vsprintf(
'<div class="radio%s"%s><label><input type="radio" name="%s" id="%s" value="%s" %s />%s</label></div>',
array( $_style, $atts, $_key, $__id, $__id, $input_atts, $__value )
);
}
}
// Button templates.
if ( 'buttons' === $_field['input_form'] ) {
foreach ( $_field['values'] as $__id => $__value ) {
$toggle = ( ! empty( $__value[1] ) ) ? ' data-toggle="tooltip" data-placement="top" title="' . $__value[1] . '" data-original-title="' . $__value[1] . '"' : '';
$__atts = ( $__id == $_field['value'] ) ? ' active' : ''; // Keep the loosely == equal operator instead of the strict === identical operator
$__atts .= ( $_field['disabled'] ) ? ' disabled' : '';
$input_values .= vsprintf(
'<label class="btn btn-default %s"><input type="radio" name="%s" id="%s" value="%s" %s /><div class="icon-in-label ndd-spot-icon icon-style-1"%s><div class="ndd-icon-main-element">%s</div></div></label>',
array( $__atts, $_key, $__id, $__id, $__id === $_field['value'] ? 'checked' : '', $toggle, $__value[0] )
);
}
}
// Input templates.
$templates = array(
'text' => array( '%s', array( $_field['value'] ) ),
'radio' => array( '%s', array( $input_values ) ),
'buttons' => array( '<div class="btn-group%s" data-toggle="buttons" id="btn-group-style-circle">%s</div>', array( $atts, $input_values ) ),
'input_color' => array(
'<input type="color" class="form-control" id="%s" name="%s" value="%s"%s /><span class="input-group-addon" id="color-text-color-hex">%s</span>',
array( $_key, $_key, $_field['value'], $atts, $_field['value'] ),
),
'input_text' => array(
'<input type="text" class="form-control" id="%s" name="%s" value="%s"%s />',
array( $_key, $_key, stripslashes( $_field['value'] ), $atts ),
),
'checkbox' => array(
'<input type="checkbox" id="%s" name="%s" value="1"%s />',
array( $_key, $_key, $atts ),
),
'header' => array(
'<h4 class="col-sm-5">%s</h4><div style="clear: both;"></div>',
array( $_field['label'] ),
),
);
// The input.
$input = vsprintf(
$templates[ $_field['input_form'] ][0],
$templates[ $_field['input_form'] ][1]
);
// The input addon.
if ( isset( $_field['post_input'] ) && ! empty( $_field['post_input'] ) ) {
$input .= sprintf( '<span class="input-group-addon">%s</span>', $_field['post_input'] );
}
// The description.
if ( isset( $_field['description'] ) && ! empty( $_field['description'] ) ) {
$description = vsprintf(
' <img src="%s" data-toggle="tooltip" data-placement="top" title="%s" data-original-title="%s" />',
array( $this->atts['tooltip_img'], $_field['description'], $_field['description'] )
);
}
// The label.
$label_class = isset( $this->atts['label_class'] ) ? $this->atts['label_class'] : 'col-sm-6';
$label_class = isset( $_field['label_class'] ) ? $_field['label_class'] : $label_class;
if ( isset( $_field['label'] ) && $add_label ) {
$label = vsprintf(
'<label for="%s" class="%s">%s</label>',
array( $_key, 'control-label ' . $label_class, $_field['label'] . $description )
);
}
// The Bootstrap 4 form-group wrapper.
if ( $group_wrap ) {
$_field['disabled'] = ( $this->atts['disable_pro'] && isset( $_field['pro'] ) && $_field['pro'] ) ? true : false;
$class = ( isset( $_field['disabled'] ) && $_field['disabled'] ) ? ' disabled' : '';
$input = vsprintf(
'<div class="%s"%s>%s<div class="%s">%s</div></div>',
array( 'form-group' . $class, '', $label, 'input-group input-group-' . $_field['input_form'], $input )
);
}
return $input;
}
/**
* Validate the $_POST values.
*
* @param array $post The $_POST values.
*/
public function validate( $post ) {
// Filter the $post array for allowed fields.
$post = array_intersect_key( $post, array_fill_keys( array_keys( $this->fields ), '' ) );
foreach ( $this->fields as $_key => $settings ) {
$reset = array();
// Validate only fields from the current section.
if ( isset( $this->atts['section'] ) && $settings['section'] !== $this->atts['section'] ) {
if ( 'header' !== $settings['input_form'] && 'text' !== $settings['input_form'] && isset( $settings['value'] ) ) {
$post[ $_key ] = isset( $this->current_values[ $_key ] ) ? $this->current_values[ $_key ] : $settings['value'];
}
continue;
}
// Add the unchecked checkboxes.
if ( 'checkbox' === $settings['input_form'] ) {
$post[ $_key ] = isset( $post[ $_key ] ) ? true : false;
}
// Validate colors.
if ( 'input_color' === $settings['input_form'] && isset( $post[ $_key ] ) && ! preg_match( '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/', $post[ $_key ] ) ) {
$reset = array(
/* translators: 1: field label 2: value */
__( 'Unrecognized %1$s. The value was reset to %2$s' ),
array( '<b>' . $settings['label'] . '</b>', '<b>' . $settings['value'] . '</b>' ),
);
}
// Sanitize text inputs.
if ( 'input_text' === $settings['input_form'] ) {
$post[ $_key ] = isset( $post[ $_key ] ) ? sanitize_text_field( wp_unslash( $post[ $_key ] ) ) : (string) $settings['value'];
}
// Validate button and radio inputs.
if ( in_array( $settings['input_form'], array( 'button', 'radio' ), true ) && isset( $post[ $_key ] ) && ! array_key_exists( $post[ $_key ], $settings['values'] ) ) {
$reset = array(
/* translators: 1: field label 2: value */
__( 'Unrecognized %1$s. The value was reset to %2$s' ),
array( '<b>' . $settings['label'] . '</b>', '<b>' . $settings['value'] . '</b>' ),
);
}
// Validate according to a rule.
if ( isset( $settings['validate'] ) && isset( $post[ $_key ] ) ) {
if ( 'int' === $settings['validate']['type'] ) {
if ( (string) (int) $post[ $_key ] !== $post[ $_key ] ) {
$this->add_message(
'info',
vsprintf(
/* translators: 1: field label 2: value */
__( 'The %1$s field accepts only an integer value. It was set to %2$s' ),
array( '<b>' . $settings['label'] . '</b>', (int) $post[ $_key ] )
)
);
}
$post[ $_key ] = (int) $post[ $_key ];
}
if ( 'float' === $settings['validate']['type'] ) {
if ( (string) (float) $post[ $_key ] !== $post[ $_key ] ) {
$this->add_message(
'info',
vsprintf(
/* translators: 1: field label 2: value */
__( 'The %1$s field accepts only a number. It was set to %2$s' ),
array( '<b>' . $settings['label'] . '</b>', (float) $post[ $_key ] )
)
);
}
$post[ $_key ] = (float) $post[ $_key ];
}
if ( in_array( $settings['validate']['type'], array( 'int', 'float' ), true ) &&
( $post[ $_key ] < $settings['validate']['range'][0] ||
$post[ $_key ] > $settings['validate']['range'][1] ) ) {
$reset = array(
/* translators: 1: field label 2: minimum value 3: maximum value 4: value */
__( '%1$s accepts values between %2$s and %3$s. Your value was reset to %4$s' ),
array( '<b>' . $settings['label'] . '</b>', $settings['validate']['range'][0], $settings['validate']['range'][1], '<b>' . $settings['value'] . '</b>' ),
);
}
}
// Reset the value and add the info message.
if ( count( $reset ) > 0 ) {
$post[ $_key ] = $settings['value'];
$this->add_message( 'info', vsprintf( $reset[0], $reset[1] ) );
}
}
return $post;
}
/**
* Add messages.
*
* @param string $type The message type.
* @param string $message The message.
*/
public function add_message( $type = '', $message = '' ) {
$this->messages[] = array( $type, $message );
}
/**
* Render the messages.
*
* @return string Messages.
*/
public function render_messages() {
if ( 0 === count( $this->messages ) ) {
return;
}
$output = '';
foreach ( $this->messages as $_message ) {
$output .= vsprintf(
'<div class="alert alert-%s"><button type="button" class="close" data-dismiss="alert">&times;</button>%s</div>',
array( $_message[0], $_message[1] )
);
}
$output = sprintf( '<div class="col-lg-12">%s</div>', $output );
return $output;
}
}
}

View File

@@ -0,0 +1,111 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( !class_exists('SilkyPress_PremiumTooltips') ) {
/**
* SilkyPress_PremiumTooltips
*/
class SilkyPress_PremiumTooltips {
/**
* Constructor
*/
public function __construct($message) {
$this->html($message);
$this->css();
$this->javascript();
}
function html($message) {
?>
<div id="skp-premium-tooltip">
<div class="skp-premium-tooltip--arrow">
<div style=""></div>
</div>
<div class="skp-premium-tooltip--msg">
<label><?php echo $message; ?></label>
</div>
</div>
<?php
}
function css() {
?>
<style type="text/css">
#skp-premium-tooltip {
display:none;
width: 230px;
height: 60px;
position: absolute;
margin-left: 354px;
margin-top: 112px;
color: white;
}
#skp-premium-tooltip .skp-premium-tooltip--arrow {
float:left;
width:13px;
}
#skp-premium-tooltip .skp-premium-tooltip--arrow div {
width: 0px;
height: 0px;
border-top: 6px solid transparent;
border-right: 6px solid #333333;
border-bottom: 6px solid transparent;
float: right;
margin-right: 0px;
margin-top: 16px;
}
#skp-premium-tooltip .skp-premium-tooltip--msg {
font-family:sans-serif;
font-size:13px;
text-align: center;
border-radius: 5px;
float: left;
background-color: rgb(51, 51, 51);
color: white;
width: 210px;
padding: 10px 0px;
}
</style>
<?php
}
function javascript() {
?>
<script type="text/javascript">
jQuery(document).ready(function($){
$(".form-group.disabled-short, .form-group.disabled").on('click',function(e){
if(typeof window.tooltip != "undefined"){
clearTimeout(window.tooltip);
}
var inputCon = $(e.currentTarget).find(".input-group");
var left = 30;
$(e.currentTarget).children().each(function(i, child){
left += $(child).width();
});
var offsetTop = $(e.currentTarget).offset().top - 38;
offsetTop -= $('h2').offset().top - 52;
$("#skp-premium-tooltip").css({"margin-left" : left + "px", "margin-top" : offsetTop + "px"});
$("#skp-premium-tooltip").fadeIn( "slow", function() {
window.tooltip = setTimeout(function(){ $("#skp-premium-tooltip").hide(); }, 1000);
});
return;
});
});
</script>
<?php
}
}
}

View File

@@ -0,0 +1,110 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( !class_exists('SilkyPress_Warnings') ) {
/**
* SilkyPress_Warnings
*/
class SilkyPress_Warnings {
var $allowed_actions = array();
var $notices = array();
/**
* Constructor
*/
public function __construct($allowed_actions) {
$this->allowed_actions = $allowed_actions;
add_action( 'wp_ajax_sk_dismiss_warning', array( $this, 'notice_dismiss' ) );
}
/**
* Check if we are on the right page
*/
function is_url( $url_part = '' ) {
if ( !isset( $_SERVER ) || !isset( $_SERVER['REQUEST_URI'] ) ) {
return false;
}
if ( strpos( $_SERVER['REQUEST_URI'], $url_part ) !== false ) {
return true;
}
return false;
}
/**
* Add this message to the $this->notices array
*/
function add_notice($id, $message, $class = '') {
if ( get_option($id) != false ) return false;
$notice = array(
'id' => $id,
'message' => $message,
);
if ( !empty($class) ) $notice['class'] = $class;
$this->notices[] = $notice;
}
function show_warnings() {
add_action( 'admin_notices', array($this, 'show_admin_notice') );
}
/**
* Show the admin notices
* */
function show_admin_notice() {
if ( !is_array($this->notices) || count($this->notices) == 0 ) return;
foreach( $this->notices as $_n ) {
$nonce = wp_create_nonce( $_n['id'] );
if ( !isset($_n['class'])) $_n['class'] = 'notice notice-warning is-dismissible';
$_n['class'] .= ' sk-notice-dismiss';
printf( '<div class="%1$s" id="%2$s" data-nonce="%3$s"><p>%4$s</p></div>', $_n['class'], $_n['id'], $nonce, $_n['message'] );
}
?>
<script type='text/javascript'>
jQuery(function($){
$(document).on( 'click', '.sk-notice-dismiss', function() {
var id = $(this).attr('id');
var data = {
action: 'sk_dismiss_warning',
option: id,
nonce: $(this).data('nonce'),
};
$.post(ajaxurl, data, function(response ) {
$('#'+id).fadeOut('slow');
});
});
});
</script>
<?php
}
/**
* Ajax response for `notice_dismiss` action
*/
function notice_dismiss() {
$option = $_POST['option'];
if ( ! in_array($option, $this->allowed_actions ) ) return;
check_ajax_referer( $option, 'nonce' );
update_option( $option, 1 );
wp_die();
}
}
}

View File

@@ -0,0 +1,111 @@
<?php
/**
* The right column on the admin side
*
* @package WPMultiStepCheckout
*/
defined( 'ABSPATH' ) || exit;
$now = time();
$wmsc_activation_time = get_option( 'wmsc_activation_time', '' );
$wmsc_version = get_option( 'wmsc_version', '' );
if ( empty( $wmsc_activation_time ) || version_compare( $wmsc_version, WMSC_VERSION, '<' ) ) {
$wmsc_activation_time = $now;
update_option( 'wmsc_activation_time', $now );
update_option( 'wmsc_version', WMSC_VERSION);
}
$show_discount = false;
if ( $now - 3*86400 < $wmsc_activation_time ) {
$show_discount = true;
}
$start_date = date('j M', $wmsc_activation_time - 3*86400 );
$end_date = date('j M', $wmsc_activation_time + 2*86400 );
function iz_convert_numbers_letters( $text, $from = 'numbers' ) {
$alphabet = str_split('abcdefghij');
$numbers = str_split('0123456789');
if ( $from == 'numbers' ) {
return str_replace( $numbers, $alphabet, $text );
} else {
return str_replace( $alphabet, $numbers, $text );
}
}
$offer_link = 'https://www.silkypress.com/woocommerce-multi-step-checkout-pro/?a=' . iz_convert_numbers_letters( $wmsc_activation_time ) . '&utm_source=wordpress&utm_campaign=iz_offer&utm_medium=banner';
$images_url = site_url().'/wp-content/plugins/wp-multi-step-checkout/assets/images/';
?>
<style type="text/css">
#right_column_metaboxes a.button {
color: #fff !important;
border: none;
box-shadow: none;
vertical-align: middle;
font-size: 14px;
height: 32px;
line-height: 32px;
padding: 0 18px 1px;
background: #bc1117 !important;
display: block-inline;
text-align: center;
margin: 10px auto;
}
#wpbody-content .metabox-holder.rating {
background: url(<?php echo $images_url; ?>rating.png) 100% 80% no-repeat;
background-size: auto auto;
background-size: 50%;
}
#wpbody-content .metabox-holder.discount {
background: url(<?php echo $images_url; ?>discount.png) 102% 102% no-repeat;
background-size: auto auto;
background-size: 50%;
}
</style>
<div id="right_column_metaboxes">
<?php if ( $show_discount ) : ?>
<div class="panel main_container">
<div class="container_title">
<h3><img src="<?php echo $images_url; ?>checkout-cart.svg" width="24" /> <?php _e('WooCommerce Multi-Step Checkout Pro', 'wp-multi-step-checkout'); ?></h3>
</div>
<div class="metabox-holder discount" style="text-align: center;">
<p>Shhh... Can you keep a secret?</p>
<p>
<span style="color: #bc1117; font-size: 24px;">30% OFF</span><br />
only between <span style="color: #bc1117;"><?php echo $start_date; ?> - <?php echo $end_date; ?></span>.
</p>
<p>Don't tell anyone.</p>
<p style="text-align: center;">
<a href="<?php echo $offer_link; ?>" target="_blank" class="button" rel="noreferrer"><?php _e('Upgrade to PRO', 'wp-multi-step-checkout'); ?></a>
</p>
</div>
</div>
<?php endif; ?>
<div class="panel main_container">
<div class="container_title">
<h3><?php _e('Like this Plugin?', 'wp-multi-step-checkout'); ?></h3>
</div>
<div class="metabox-holder rating" style="text-align: center;">
<p><?php _e('Share your opinion with the world on the WordPress.org Plugin Repository.', 'wp-image-zoooom'); ?></p>
<p><a href="https://wordpress.org/plugins/wp-multi-step-checkout/" target="_blank" class="button"><?php _e('Rate it on WordPress.org', 'wp-image-zoooom'); ?></a></p>
</div>
</div>
</div>
<div style="clear: both"></div>

View File

@@ -0,0 +1,535 @@
<?php
/**
* Functions
*
* @package WPMultiStepCheckout
*/
defined( 'ABSPATH' ) || exit;
if ( ! function_exists( 'get_wmsc_settings' ) ) {
/**
* The settings array for the admin page.
*/
function get_wmsc_settings() {
$account_url = admin_url( 'admin.php?page=wc-settings&tab=account' );
$no_login_screenshot = 'https://www.silkypress.com/wp-content/uploads/2018/09/multi-step-checkout-no-login.png';
$registration_settings_screenshot = 'https://www.silkypress.com/wp-content/uploads/2019/09/registration-description.png';
$wmsc_settings = array(
/* General Settings */
'label1' => array(
'label' => __( 'Which Steps to show', 'wp-multi-step-checkout' ),
'input_form' => 'header',
'value' => '',
'section' => 'general',
),
'show_shipping_step' => array(
'label' => __( 'Show the <code>Shipping</code> step', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => true,
'section' => 'general',
),
'show_login_step' => array(
'label' => __( 'Show the <code>Login</code> step', 'wp-multi-step-checkout' ),
'input_form' => 'text',
/* translators: 1: Woocommerce Accounts URL 2: Screenshot URL. */
'value' => sprintf( __( ' For removing the login step you need to uncheck the "Allow customers to log into an existing account during checkout" option on the <a href="%1$s">WP Admin -> WooCommerce -> Settings -> Accounts</a> page. See <a href="%2$s" target="_blank">this screenshot</a>.', 'wp-multi-step-checkout' ), esc_url( $account_url ), esc_url( $no_login_screenshot ) ),
'section' => 'general',
),
'unite_billing_shipping' => array(
'label' => __( 'Show the <code>Billing</code> and the <code>Shipping</code> steps together', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => false,
'section' => 'general',
),
'unite_order_payment' => array(
'label' => __( 'Show the <code>Order</code> and the <code>Payment</code> steps together', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => false,
'section' => 'general',
),
'label2' => array(
'label' => __( 'Additional Elements', 'wp-multi-step-checkout' ),
'input_form' => 'header',
'value' => '',
'section' => 'general',
),
'show_back_to_cart_button' => array(
'label' => __( 'Show the <code>Back to Cart</code> button', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => true,
'section' => 'general',
),
'registration_with_login' => array(
'label' => __( 'Show registration form in the <code>Login</code> step', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => true,
'section' => 'general',
'description' => __( 'The registration form will be shown next to the login form, it will not replace it', 'wp-multi-step-checkout' ),
'pro' => true,
),
'registration_desc' => array(
'label' => '',
'input_form' => 'text',
/* translators: 1: Woocommerce Accounts URL 2: Screenshot URL. */
'value' => sprintf( __( 'Use the "Account creation" options on the <a href="%1$s">WP Admin -> WooCommerce -> Settings -> Accounts & Privacy</a> page to modify the Registration form. See <a href="%2$s" target="_blank">this screenshot</a>.', 'wp-multi-step-checkout' ), esc_url( $account_url ), esc_url( $registration_settings_screenshot ) ),
'section' => 'general',
'pro' => true,
),
'review_thumbnails' => array(
'label' => __( 'Add product thumbnails to the <code>Order Review</code> section', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => true,
'section' => 'general',
'pro' => true,
),
'review_address' => array(
'label' => __( 'Add <code>Address Review</code> to the <code>Order</code> section', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => false,
'section' => 'general',
'pro' => true,
),
'label3' => array(
'label' => __( 'Functionality', 'wp-multi-step-checkout' ),
'input_form' => 'header',
'value' => '',
'section' => 'general',
),
'validation_per_step' => array(
'label' => __( 'Validate the fields during each step', 'wp-multi-step-checkout' ),
'description' => __( 'The default WooCommerce validation is done when clicking the Place Order button. With this option the validation is performed when trying to move to the next step', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => true,
'section' => 'general',
'pro' => true,
),
'clickable_steps' => array(
'label' => __( 'Clickable Steps', 'wp-multi-step-checkout' ),
'description' => __( 'The user can click on the steps in order to get to the next one.', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => true,
'section' => 'general',
'pro' => true,
),
'keyboard_nav' => array(
'label' => __( 'Enable the keyboard navigation', 'wp-multi-step-checkout' ),
'description' => __( 'Use the keyboard\'s left and right keys to move between the checkout steps', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => false,
'section' => 'general',
),
'url_hash' => array(
'label' => __( 'Change the URL for each step', 'wp-multi-step-checkout' ),
'description' => __( 'Each step will have a hash added to the URL. For example &quot;#login&quot; or &quot;#billing&quot;. This option, together with some &quot;History Change Trigger&quot; settings in the Google Tag Manager, allows Google Analytics to track each step as different pages.', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => false,
'section' => 'general',
'pro' => true,
),
/* Templates */
'main_color' => array(
'label' => __( 'Main Color', 'wp-multi-step-checkout' ),
'input_form' => 'input_color',
'value' => '#1e85be',
'section' => 'design',
),
'template' => array(
'label' => __( 'Template', 'wp-multi-step-checkout' ),
'input_form' => 'radio',
'value' => 'default',
'values' => array(
'default' => __( 'Default', 'wp-multi-step-checkout' ),
'md' => __( 'Material Design', 'wp-multi-step-checkout' ),
'breadcrumb' => __( 'Breadcrumbs', 'wp-multi-step-checkout' ),
),
'section' => 'design',
'pro' => true,
),
'wpmc_buttons' => array(
'label' => __( 'Use the plugin\'s buttons', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => false,
'description' => __( 'By default the plugin tries to use the theme\'s design for the buttons. If this fails, enable this option in order to use the plugin\'s button style', 'wp-multi-step-checkout' ),
'section' => 'design',
'pro' => true,
),
'wpmc_check_sign' => array(
'label' => __( 'Show a "check" sign for visited steps', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => false,
'section' => 'design',
'pro' => true,
),
'visited_color' => array(
'label' => __( 'Visited steps color', 'wp-multi-step-checkout' ),
'input_form' => 'input_color',
'value' => '#1EBE3A',
'section' => 'design',
'pro' => true,
),
/* Step Titles */
't_login' => array(
'label' => __( 'Login', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => __( 'Login', 'wp-multi-step-checkout' ),
'section' => 'titles',
),
't_billing' => array(
'label' => __( 'Billing', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => __( 'Billing', 'wp-multi-step-checkout' ),
'section' => 'titles',
),
't_shipping' => array(
'label' => __( 'Shipping', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => __( 'Shipping', 'wp-multi-step-checkout' ),
'section' => 'titles',
),
't_order' => array(
'label' => __( 'Order', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => __( 'Order', 'wp-multi-step-checkout' ),
'section' => 'titles',
),
't_payment' => array(
'label' => __( 'Payment', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => __( 'Payment', 'wp-multi-step-checkout' ),
'section' => 'titles',
),
't_back_to_cart' => array(
'label' => __( 'Back to cart', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => _x( 'Back to cart', 'Frontend: button label', 'wp-multi-step-checkout' ),
'section' => 'titles',
),
't_skip_login' => array(
'label' => __( 'Skip Login', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => _x( 'Skip Login', 'Frontend: button label', 'wp-multi-step-checkout' ),
'section' => 'titles',
),
't_previous' => array(
'label' => __( 'Previous', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => _x( 'Previous', 'Frontend: button label', 'wp-multi-step-checkout' ),
'section' => 'titles',
),
't_next' => array(
'label' => __( 'Next', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => _x( 'Next', 'Frontend: button label', 'wp-multi-step-checkout' ),
'section' => 'titles',
),
't_error' => array(
'label' => __( 'Please fix the errors on this step before moving to the next step', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => _x( 'Please fix the errors on this step before moving to the next step', 'Frontend: error message', 'wp-multi-step-checkout' ),
'section' => 'titles',
'description' => __( 'This is an error message shown in the frontend', 'wp-multi-step-checkout' ),
'pro' => true,
),
'c_sign' => array(
'label' => __( 'AND sign', 'wp-multi-step-checkout' ),
'input_form' => 'input_text',
'value' => __( '&', 'wp-multi-step-checkout' ),
'section' => 'titles',
'description' => __( 'The sign between two unified steps. For example "Billing & Shipping"' ),
),
't_wpml' => array(
'label' => __( 'Use WPML to translate the text on the Steps and Buttons', 'wp-multi-step-checkout' ),
'input_form' => 'checkbox',
'value' => false,
'section' => 'titles',
'description' => __( 'For a multilingual website the translations from WPML will be used instead of the ones in this form', 'wp-multi-step-checkout' ),
),
);
return apply_filters( 'wmsc_settings_admin', $wmsc_settings );
}
}
if ( ! function_exists( 'get_wmsc_steps' ) ) {
/**
* The steps array.
* Note: The Login is always the first step and is not part of the get_wmsc_steps() array.
*/
function get_wmsc_steps() {
$steps = array(
'billing' => array(
'title' => __( 'Billing', 'wp-multi-step-checkout' ),
'position' => 10,
'class' => 'wpmc-step-billing',
'sections' => array( 'billing' ),
),
'shipping' => array(
'title' => __( 'Shipping', 'wp-multi-step-checkout' ),
'position' => 20,
'class' => 'wpmc-step-shipping',
'sections' => array( 'shipping' ),
),
'review' => array(
'title' => __( 'Order', 'wp-multi-step-checkout' ),
'position' => 30,
'class' => 'wpmc-step-review',
'sections' => array( 'review' ),
),
'payment' => array(
'title' => __( 'Payment', 'wp-multi-step-checkout' ),
'position' => 40,
'class' => 'wpmc-step-payment',
'sections' => array( 'payment' ),
),
);
return $steps;
}
}
if ( ! function_exists( 'wmsc_step_content_login' ) ) {
/**
* The content for the Login step.
*
* @param object $checkout The Checkout object from the WooCommerce plugin.
* @param bool $stop_at_login If the user should be logged in in order to checkout.
*/
function wmsc_step_content_login( $checkout, $stop_at_login ) { ?>
<div class="wpmc-step-item wpmc-step-login">
<div id="checkout_login" class="woocommerce_checkout_login wp-multi-step-checkout-step">
<?php
woocommerce_login_form(
array(
'message' => apply_filters( 'woocommerce_checkout_logged_in_message', __( 'If you have shopped with us before, please enter your details in the boxes below. If you are a new customer, please proceed to the Billing &amp; Shipping section.', 'wp-multi-step-checkout' ) ),
'redirect' => wc_get_page_permalink( 'checkout' ),
'hidden' => false,
)
);
?>
</div>
<?php
if ( $stop_at_login ) {
echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', __( 'You must be logged in to checkout.', 'woocommerce' ) ) );
}
?>
</div>
<?php }
}
if ( ! function_exists( 'wmsc_step_content_billing' ) ) {
/**
* The content of the Billing step.
*/
function wmsc_step_content_billing() {
do_action( 'woocommerce_checkout_before_customer_details' );
do_action( 'woocommerce_checkout_billing' );
}
}
if ( ! function_exists( 'wmsc_step_content_shipping' ) ) {
/**
* The content of the Shipping step.
*/
function wmsc_step_content_shipping() {
do_action( 'woocommerce_checkout_shipping' );
do_action( 'woocommerce_checkout_after_customer_details' );
}
}
if ( ! function_exists( 'wmsc_step_content_payment' ) ) {
/**
* The content of the Order Payment step.
*/
function wmsc_step_content_payment() {
echo '<h3 id="payment_heading">' . esc_html__( 'Payment', 'woocommerce' ) . '</h3>';
do_action( 'wpmc-woocommerce_checkout_payment' );
do_action( 'woocommerce_checkout_after_order_review' );
}
}
if ( ! function_exists( 'wmsc_step_content_review' ) ) {
/**
* The content of the Order Review step.
*/
function wmsc_step_content_review() {
do_action( 'woocommerce_checkout_before_order_review_heading' );
echo '<h3 id="order_review_heading">' . esc_html__( 'Your order', 'woocommerce' ) . '</h3>';
do_action( 'woocommerce_checkout_before_order_review' );
echo '<div id="order_review" class="woocommerce-checkout-review-order">';
do_action( 'woocommerce_checkout_order_review' );
do_action( 'wpmc-woocommerce_order_review' );
echo '</div>';
}
}
if ( ! function_exists( 'wmsc_step_content_payment_germanized' ) ) {
/**
* The content of the Payment step for the "Germanized for WooCommerce" plugin.
*/
function wmsc_step_content_payment_germanized() {
echo '<h3 id="payment_heading">' . esc_html__( 'Choose a Payment Gateway', 'woocommerce-germanized' ) . '</h3>';
do_action( 'wpmc-woocommerce_checkout_payment' );
}
}
if ( ! function_exists( 'wmsc_step_content_review_germanized' ) ) {
/**
* The content of the Order Review step for the "Germanized for WooCommerce" plugin.
*/
function wmsc_step_content_review_germanized() {
do_action( 'woocommerce_checkout_before_order_review_heading' );
echo '<h3 id="order_review_heading">' . esc_html__( 'Your order', 'woocommerce' ) . '</h3>';
do_action( 'woocommerce_checkout_before_order_review' );
echo '<div id="order_review" class="woocommerce-checkout-review-order">';
do_action( 'wpmc-woocommerce_order_review' );
if ( function_exists( 'woocommerce_gzd_template_order_submit' ) ) {
woocommerce_gzd_template_order_submit();
}
echo '</div>';
}
}
if ( ! function_exists( 'wmsc_step_content_review_german_market' ) ) {
/**
* The content of the Order Review step for the "German Market" plugin.
*/
function wmsc_step_content_review_german_market() {
do_action( 'woocommerce_checkout_before_order_review_heading' );
echo '<h3 id="order_review_heading">' . esc_html__( 'Your order', 'woocommerce' ) . '</h3>';
do_action( 'woocommerce_checkout_before_order_review' );
echo '<div id="order_review" class="woocommerce-checkout-review-order">';
do_action( 'wpmc-woocommerce_order_review' );
do_action( 'woocommerce_checkout_order_review' );
echo '</div>';
}
}
if ( ! function_exists( 'wmsc_step_content_payment_german_market' ) ) {
/**
* The content of the Order Payment step for the "German Market" plugin.
*/
function wmsc_step_content_payment_german_market() {
echo '<h3 id="payment_heading">' . esc_html__( 'Payment', 'woocommerce' ) . '</h3>';
do_action( 'wpmc-woocommerce_checkout_payment' );
}
}
if ( ! function_exists( 'wpmc_sort_by_position' ) ) {
/**
* Comparison function for sorting the steps.
*
* @param array $a First array.
* @param array $b Second array.
*/
function wpmc_sort_by_position( $a, $b ) {
return $a['position'] - $b['position'];
}
}
if ( ! function_exists( 'wmsc_delete_step_by_category' ) ) {
/**
* Delete a step if one/all products in a category or not in a category.
*
* Use the `wmsc_delete_step_by_category` filter to set up the settings.
*
* @param array $steps The steps array.
*/
function wmsc_delete_step_by_category( $steps ) {
$settings = apply_filters(
'wmsc_delete_step_by_category',
array(
'remove_step' => 'shipping',
'one_product_in_categories' => array(),
'all_products_in_categories' => array(),
'one_product_in_all_except_categories' => array(),
'all_products_in_all_except_categories' => array(),
)
);
extract( $settings );
$cart = WC()->cart->get_cart_contents();
$products = array();
if ( ! is_array( $cart ) || count( $cart ) === 0 ) {
return $steps;
}
foreach ( $cart as $_product ) {
$this_product_in_category = false;
$_cat = get_the_terms( $_product['product_id'], 'product_cat' );
if ( is_array( $_cat ) && count( $_cat ) > 0 ) {
foreach ( $_cat as $__cat ) {
$products[ $_product['product_id'] ][] = $__cat->slug;
}
}
}
if ( count( $products ) === 0 ) {
return $steps;
}
$products_intersect = $products_union = array_shift( $products );
while ( count( $products ) > 0 ) {
$one_product = array_shift( $products );
$products_intersect = array_intersect( $products_intersect, $one_product );
$products_union = array_merge( $products_union, $one_product );
}
if ( count( $one_product_in_categories ) > 0 ) {
foreach ( $one_product_in_categories as $_cat ) {
if ( array_search( $_cat, $products_union, true ) !== false ) {
unset( $steps[ $remove_step ] );
}
}
}
if ( count( $all_products_in_categories ) > 0 ) {
foreach ( $all_products_in_categories as $_cat ) {
if ( array_search( $_cat, $products_intersect, true ) !== false ) {
unset( $steps[ $remove_step ] );
}
}
}
if ( count( $one_product_in_all_except_categories ) > 0 ) {
if ( count( array_intersect( $one_product_in_all_except_categories, $products_union ) ) === 0 ) {
unset( $steps[ $remove_step ] );
}
}
if ( count( $all_products_in_all_except_categories ) > 0 ) {
if ( count( array_intersect( $all_products_in_all_except_categories, $products_intersect ) ) === 0 ) {
unset( $steps[ $remove_step ] );
}
}
return $steps;
}
}
add_filter( 'wpmc_modify_steps', 'wmsc_delete_step_by_category', 30 );