Skip to content
Snippets Groups Projects
Commit 2a0f2a4a authored by Reinhold Kainhofer's avatar Reinhold Kainhofer
Browse files

First attempts; Config UI halfway finished, library interface should work. No testing yet

parents
Branches
Tags
No related merge requests found
Showing
with 1821 additions and 0 deletions
sync.sh
Material
This diff is collapsed.
Makefile 0 → 100644
BASE=ordernumbers
PLATTFORM=woocommerce
VENDOR=opentools
VERSION=1.1
DIR = $(shell pwd)
SVNDIR=wordpress-plugin-svn
BUILDDIR=.build/
BASICBUILDDIR=$(VENDOR)-$(PLATTFORM)-$(BASE)-basic
ADVBUILDDIR=$(VENDOR)-$(PLATTFORM)-$(BASE)-advanced
PLUGINFILES=library assets ordernumber_helper_woocommerce.php ordernumbers_woocommerce_basic.php readme.txt LICENSE.txt
BASICPLUGINFILES=woocommerce-basic-ordernumbers.php
ADVPLUGINFILES=woocommerce-advanced-ordernumbers.php ordernumbers_woocommerce.php
TRANSLATIONS=
ZIPFILE=$(VENDOR)-$(PLATTFORM)-$(BASE)-basic_v$(VERSION).zip
ADVZIPFILE=$(VENDOR)-$(PLATTFORM)-$(BASE)-advanced_v$(VERSION).zip
all: zip
zip: $(PLUGINFILES) $(ADVPLUGINFILES) $(BASICPLUGINFILES) $(TRANSLATIONS)
echo $(DIR)
@echo "Packing basic plugin version into distribution file $(ZIPFILE):"
mkdir -p $(BUILDDIR)/$(BASICBUILDDIR)
cp --parents -r $(PLUGINFILES) $(BASICPLUGINFILES) $(TRANSLATIONS) $(BUILDDIR)/$(BASICBUILDDIR)
cd $(BUILDDIR) && zip -r $(DIR)/$(ZIPFILE) $(BASICBUILDDIR)
# @zip -r
mkdir -p $(BUILDDIR)/$(ADVBUILDDIR)
echo `pwd`mak
cp --parents -r $(PLUGINFILES) $(ADVPLUGINFILES) $(TRANSLATIONS) $(BUILDDIR)/$(ADVBUILDDIR)
cp readme-adv.txt $(BUILDDIR)/$(ADVBUILDDIR)/readme.txt
cd $(BUILDDIR) && zip -r $(DIR)/$(ADVZIPFILE) $(ADVBUILDDIR)
cd $(DIR)
clean:
rm -f $(ZIPFILE) $(ADVZIPFILE) $(BUILDDIR) $(ADVBUILDDIR)
$(SVNDIR)/tags/$(VERSION) :
cd $(SVNDIR) && svn cp trunk tags/$(VERSION)
svn: $(SVNDIR)/trunk $(SVNDIR)/tags/$(VERSION)
rsync -avP $(PLUGINFILES) $(BASICPLUGINFILES) $(TRANSLATIONS) $(SVNDIR)/trunk
svn-release: svn $(SVNDIR)/tags/$(VERSION)
rsync -avP $(PLUGINFILES) $(BASICPLUGINFILES) $(TRANSLATIONS) $(SVNDIR)/tags/$(VERSION)
\ No newline at end of file
TODO 0 → 100644
OpenTools Shipping by Rules for WooCommerce - Open TODOs
========================================================
table.rules_shipping_methods th {
padding-left: 10px;
}
table.rules_shipping_methods .name {
}
table.rules_shipping_methods.widefat {
background: inherited;
}
div.shipping_rules_ruleset {
background: #f8f8f8;
border: #D0D0D0 1px solid;
margin-bottom: 10px;
margin-top: 10px;
}
#shipping_rules_rulesets .ruleset_openclose {
cursor: pointer;
float: right;
width: 27px;
height: 30px;
}
#shipping_rules_rulesets .shipping_rules_ruleset.closed .inside {
display: none;
}
#shipping_rules_rulesets .shipping_rules_ruleset.closed .ruleset_openclose:before {
content: '\f141';
}
#shipping_rules_rulesets .shipping_rules_ruleset .ruleset_openclose:before {
content: '\f142';
}
#shipping_rules_rulesets .ruleset_openclose:before {
/* right: 12px; */
font: 400 20px/1 dashicons;
speak: none;
display: inline-block;
padding: 2px;
top: 0;
position: relative;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-decoration: none!important;
width: 100%;
height: 100%;
}
#poststuff div.shipping_rules_ruleset h3 {
padding-top: 3px;
padding-bottom: 3px;
}
.form-table td.shipping_rules_rulescell {
padding-left: 0;
}
.form-table textarea.shipping_rules_rule_textarea {
width: 100%;
}
#shipping_rules_rulesets .form-table th.titledesc {
padding-bottom: 12px;
padding-top: 8px;
font-weight: normal;
}
#shipping_rules_rulesets .form-table td.forminp {
padding-bottom: 0;
padding-top: 0;
}
.ruleset-box-header {
width: 100%;
height: 30px;
/* border: 1px solid #808080; */
border-bottom: 1px solid #D0D0D0;
}
.ruleset-box-header .input-wrap {
display: block;
overflow: hidden;
/* height: 1.5em; */
height: 100%;
/* border: 1px solid #D0D0D0; */
}
.ruleset-box-header input.ruleset_name {
width: 100%;
/* height: 100%; */
/* padding-right: 35px; */
/* padding: 0 1em; */
margin: 2px 0;
/* border: 1px dotted red; */
}
.ruleset-box-header .ruleset_name_label {
float: left;
height: 100%;
}
/* <div class="ruleset-box-header">
<div class="ruleset_openclose" title="Click to toggle"><br></div>
<h3 class="hndle ui-sortable-handle">Ruleset:
<span class="input-wrap"><input type='text' class='ruleset_name' name='<?php echo $id; ?>[name]' placeholder='<?php _e('Name of the Ruleset', 'opentools-shippingrules'); ?>' value='<?php echo isset($ruleset['name'])?esc_attr($ruleset['name']):""; ?>'></span></h3>
</div>*/
media="all"
.woocommerce_page_wc-settings .rules_shipping_methods .add.button:before {
content: "";
}
\ No newline at end of file
/**
* Ordernumber Admin JS
*/
jQuery( function ( $ ) {
var loading_icon = '<span class="loading-icon"><img src="images/loading.gif"/></span>';
// Add new ruleset via an AJAX call
$( '#shipping_rules_rulesets' ).on( 'click', '.ruleset-add', function() {
// Display loading icon
$( '.shipping_rules_rulesets' ).append( loading_icon ).children( ':last' );
// Find the largest existing ruleset ID number (might have been reordered!):
var maxnr = 0;
$('.shipping_rules_ruleset').map(function(){
var value = parseFloat(this.getAttribute('data-nr')) || -Infinity;
maxnr = (value>maxnr) ? value : maxnr;
});
var data = {
action: 'shipping_rules_add_ruleset',
rulesetnr: maxnr+1
};
// Insert condition group
$.post( ajaxurl, data, function( response ) {
$( '.shipping_rules_rulesets .loading-icon' ).last().remove();
var appended = $( '.shipping_rules_rulesets' ).append( response ).children( ':last' );
$(appended).find( '.select2' ).select2();
$(appended).hide().fadeIn( 'normal' );
});
});
// Delete ruleset
$( '#shipping_rules_rulesets' ).on( 'click', '.ruleset-remove', function() {
$( this ).closest( '.shipping_rules_ruleset' ).fadeOut( 'normal', function() { $( this ).remove(); });
});
// Open/Close the ruleset boxes
$( '#shipping_rules_rulesets' ).on( 'click', '.ruleset-box-header', function (event) {
// If the user clicks on some form input inside the h3, like a select list (for variations), the box should not be toggled
if ($(event.target).filter(':input, option').length) return;
$( this ).closest( '.shipping_rules_ruleset' ).toggleClass('closed');
});
});
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$methods = get_posts( array( 'posts_per_page' => '-1', 'post_type' => 'shipping_rules', 'post_status' => array( 'draft', 'publish' ) ) );
?>
<tr valign="top">
<th scope="row" class="titledesc"><?php echo $this->helper->__( 'Shipping By Rules Methods' ) ?></th>
<td class="forminp" id="<?php echo $this->id; ?>_rules_shipping_methods">
<table class="rules_shipping_methods widefat striped" cellspacing="0">
<thead>
<tr>
<th class="name" ><?php echo $this->helper->__( 'Name' ); ?></th>
<th class="id" ><?php echo $this->helper->__( 'ID' ); ?></th>
<th class="status" ><?php echo $this->helper->__( 'Status' ); ?></th>
<th class="methods" ><?php echo $this->helper->__( 'Configured Rulesets' ); ?></th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
foreach ( $methods as $method ) {
$alt = '';
// $alt = ( $i++ ) % 2 == 0 ? 'alternate' : '';
?>
<tr>
<td class="name <?php echo $alt; ?>">
<input type="hidden" name="rules_method_order[]" value="<?php echo esc_attr($method->ID); ?>" />
<?php echo empty($method->post_title) ? $this->helper->__('Untitled Method') : esc_html($method->post_title); ?>
<div class='row-actions'>
<span class='edit'>
<a href='<?php echo get_edit_post_link( $method->ID ); ?>' title='<?php echo $this->helper->__( 'Edit Method'); ?>'>
<?php echo $this->helper->__('Edit'); ?>
</a>
|
</span>
<span class='trash'>
<a href='<?php echo get_delete_post_link( $method->ID ); ?>' title='<?php echo $this->helper->__('Delete Method'); ?>'><?php
echo $this->helper->__('Delete');
?></a>
</span>
</div>
</td>
<td class="id">
<?php echo esc_html($method->ID); ?>
</td>
<td class="status">
<?php
if ( $method->post_status == 'publish' ) { ?>
<span class="status-enabled tips" data-tip="<?php echo __ ( 'Enabled', 'woocommerce' ); ?>"><?php echo __ ( 'Enabled', 'woocommerce' ); ?></span>
<?php
} else {
echo '-';
}
?>
</td>
<td>
<?php
$rulesetnames = array();
$rulesets = get_post_meta( $method->ID, '_rules_shipping_ruleset', true );
if (!is_array($rulesets)) {
$rulesets = array();
}
foreach ($rulesets as $ruleset) {
if (isset($ruleset['name']) && !empty($ruleset['name'])) {
$rulesetnames[] = $ruleset['name'];
} else {
$rulesetnames[] = $this->helper->__('<Unnamed>');
}
}
if (!empty($rulesetnames)) {
echo esc_html(join(", ", $rulesetnames));
} else {
echo $this->helper->__('<em>No rulesets defined</em>');
}
?>
</td>
</tr>
<?php
}
if ( empty( $methods ) ) :
?><tr>
<td colspan='4'><?php echo $this->helper->__( 'There are no Shipping By Rules methods configured yet.' ); ?></td>
</tr><?php
endif;
?></tbody>
<tfoot>
<tr>
<th colspan='1' style='padding-left: 10px;'>
<a href='<?php echo admin_url( 'post-new.php?post_type=shipping_rules' ); ?>' class='add button'><?php echo $this->helper->__( 'Add Shipping By Rules method' ); ?></a>
</th>
<th colspan="3">
<span class="description"><?php _e( 'Drag and drop the above shipping methods to control their display order.', 'woocommerce' ); ?></span>
</th>
</tr>
</tfoot>
</table>
<script type="text/javascript">
jQuery(function() {
// Sorting
jQuery('table.rules_shipping_methods tbody').sortable({
items:'tr',
cursor:'move',
axis:'y',
handle: 'td',
scrollSensitivity:40,
helper:function(e,ui){
ui.children().each(function(){
jQuery(this).width(jQuery(this).width());
});
// ui.css('left', '0');
return ui;
},
start:function(event,ui){
ui.item.css('background-color','#f6f6f6');
},
stop:function(event,ui){
ui.item.removeAttr('style');
}
});
});
</script>
</td>
</tr>
<?php
<?php
/**
* Shipping By Rules meta box field showing one ruleset.
*
* Display one ruleset in a meta box.
*
* @author Reinhold Kainhofer, Open Tools
* @package WooCommerce Shipping Bby Rules
* @version 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
function render_meta_box_shipping_rules_single_ruleset ($post, $nr, $ruleset) {
$id = '_rules_shipping_ruleset['.absint($nr).']';
?><div class='shipping_rules shipping_rules_ruleset shipping_rules_meta_box shipping_rules_ruleset_meta_box_field' data-nr='<?php echo absint($nr); ?>'>
<div class="ruleset-box-header">
<div class="ruleset_openclose" title="Click to toggle"><br></div>
<h3 class="ruleset_name_label ui-sortable-handle">Ruleset: </h3>
<div class="input-wrap"><input type='text' class='ruleset_name' name='<?php echo $id; ?>[name]' placeholder='<?php _e('Name of the Ruleset', 'opentools-shippingrules'); ?>' value='<?php echo isset($ruleset['name'])?esc_attr($ruleset['name']):""; ?>'></div>
</div>
<div class="inside">
<input type='hidden' name='_rules_shipping_ordering[]' value='<?php echo absint($nr);?>'>
<table class='form-table'>
<tbody>
<?php
/** Country restrictions: */
$selections = isset($ruleset['countries'])?$ruleset['countries']:array();
$value = array(
// 'options' => WC()->countries->countries,
'id' => $id.'[countries]',
'title' => __('Restrict to Countries', 'opentools-shippingrules'),
'type' => 'multi_select_countries',
);
$description = '';
$tooltip_html = '';
if ( ! empty( $value['options'] ) ) {
$countries = $value['options'];
} else {
$countries = WC()->countries->countries;
}
asort( $countries );
?><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">
<select multiple="multiple" name="<?php echo esc_attr( $value['id'] ); ?>[]" data-placeholder="<?php _e( 'Choose countries (no selection means no restriction)&hellip;', 'woocommerce' ); ?>" title="<?php _e( 'Country', 'woocommerce' ) ?>" class="select2">
<?php
if ( $countries ) {
foreach ( $countries as $key => $val ) {
echo '<option value="' . esc_attr( $key ) . '" ' . selected( in_array( $key, $selections ), true, false ).'>' . $val . '</option>';
}
}
?>
</select> <?php echo ( $description ) ? $description : ''; ?>
</td>
</tr><?php
/** Rules */
$option_value = isset($ruleset['rules'])?$ruleset['rules']:'';
// $option_value='Name=Whatever; Amount>35; Shipping=5
// Name=2; contains_only(SKUs, "asdf"); Shipping=33
// State2=="AZ"; NoShipping
// Amount<5; Shipping=333
// ZIP==4321; Shipping=3
// ZIP==9999; Shipping=15
// Shipping=0
// ';
$nrrules = count(explode("\n", $option_value));
$value = array(
'id' => $id.'[rules]',
'title' => __('Rules:', 'opentools-shippingrules'),
'type' => 'textarea',
'css' => '',
'class' => 'shipping_rules_rule_textarea',
'placeholder' => __('Rules of the form:\nName="Rule name"; Amount>100; [...Conditions...]; Shipping=3', 'opentools-shippingrules'),
);
$custom_attributes = array(
'rows="'.absint(max($nrrules,5)).'"',
'cols="35"',
);
?><tr valign="top">
<td class="forminp shipping_rules_rulescell forminp-<?php echo sanitize_title( $value['type'] ) ?>" colspan="2">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><b><?php echo esc_html( $value['title'] ); ?></b></label>
<?php echo $tooltip_html; ?>
<?php echo $description; ?>
<br/>
<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
?>
</tbody>
</table>
<p class="shipping_rules_remove"><a class='button ruleset-remove' href='javascript:void(0);'><?php _e( 'Remove this ruleset', 'opentools-shippingrules' ); ?></a></p>
</div>
</div>
<?php
}
<?php
/**
* Shipping By Rules meta box Help.
*
* Display the help message / user guide for the Shipping by Rules Method.
*
* @author Reinhold Kainhofer
* @package OpenTools Shipping by Rules for WooCommerce
* @version 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
?><div class='rules_shipping rules_shipping_help rules_shipping_meta_box rules_shipping_help_meta_box'>
<ul>
<li>One rule per line, rule parts separated by Semicolon (;)</li>
<li>Rules are evaluated sequentially, first matching rule is offered</li>
<li>Typical form of a rule:
<blockquote>
Name="Rule name"; Condition1; Condition2; Shipping=123
</blockquote></li>
<li>Setting costs to NoShipping prevents method from offering any shipping</li>
<li>Conditions can contain <strong>comparison operators (&lt;, &lt;=, =&lt;, ==, !=, &lt;&gt;, &gt;=, =&gt;, &gt;)</strong>, variables and functions.</li>
<li>Some <strong>variables (case-insensitive)</strong>:
<ul>
<li><strong><tt>Amount</tt></strong>, </li>
<li><strong><tt>Weight</tt></strong>, </li>
<li><strong><tt>ZIP</tt></strong>, </li>
<li><strong><tt>Products</tt></strong> (number of different products), </li>
<li><strong><tt>Articles</tt></strong> (counted with quantity), </li>
<li><strong><tt>Volume</tt></strong> (total volume of the order)</li>
<li><strong><tt>MinVolume</tt>, <tt>MinLength</tt>, <tt>MinWidth</tt>, <tt>MinHeight</tt></strong> </li>
<li>as well as the same variables with <tt>Max</tt> instead of <tt>Min</tt>.</li>
</ul>
</li>
<li>A condition can consist of multiple chained comparisons. In the advanced version, the OR operator is available.</li>
<li>All rule parts of the form <strong><tt>[VARIABLE]=VALUE</tt> are assignments</strong>; allowed variables are
<ul>
<li><strong><tt>Name</tt></strong> (of the rule), </li>
<li><strong><tt>Shipping</tt></strong>, </li>
<li><strong><tt>ShippingWithTax</tt></strong>, </li>
<li><strong><tt>ExtraShippingCharge</tt></strong>, </li>
<li><strong><tt>ExtraShippingMultiplier</tt></strong>, </li>
<li><strong><tt>Condition</tt></strong>, </li>
<li><strong><tt>Variable</tt></strong>, </li>
<li><strong><tt>Value</tt></strong>, </li>
<li><strong><tt>Comment</tt></strong>.</li>
</ul>
The '<tt>Shipping='</tt> can be left out.</li>
<li>In the advanced version, all expressions may contain <strong>arbitrary basic arithmetic expressions (+, -, *, /, %, ^ and parentheses)</strong> of the above variables and functions like max(..), min(..), round(..), ceil(..), floor(..), day(), month(), etc..</li>
<li><strong>Alphanumeric postal codes</strong> are supported by the variables <tt>UK_Outward, UK_Area, UK_District, UK_Subdistrict, Canada_FSA, Canada_Area, Canada_Urban, Canada_Subarea, ZIP1, ZIP2, ZIP3, ZIP4, ZIP5</tt> and <tt>ZIP6</tt> in the advanced version.</li>
</ul>
<p>EXAMPLE: A rule named 'Europe' that sets shipping costs of 5€ plus 1.50€ per article for order amounts from 50 to less than 100, and free shipping from 100€ on would be:</p>
<blockquote><tt>Name=Free Shipping; 100&lt;= Amount; 0<br/>Name=Europe; 50&lt;=Amount&lt;100; Shipping=5+1.50*Articles</tt></blockquote>
<p>See also the the <a href='http://open-tools.net/documentation/shipping-by-rules-plugins-for-virtuemart.html'>Plugin's documentation</a> and <a href='http://open-tools.net/component/content/article.html?id=46'>Rules Examples</a>.</p>
</div>
<?php
\ No newline at end of file
<?php
/**
* Shipping By Rules meta box rulesets.
*
* Display the shipping rulesets in the meta box.
*
* @author Reinhold Kainhofer, Open Tools
* @package WooCommerce Shipping Bby Rules
* @version 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
function render_meta_box_shipping_rules_rulesets ($post, $rulesets) {
wp_nonce_field( 'shipping_rules_rulesets_meta_box', 'shipping_rules_rulesets_meta_box_nonce' );
?><div class='shipping_rules shipping_rules_rulesets shipping_rules_meta_box shipping_rules_rulesets_meta_box'>
<pre><?php //print_r($rulesets); ?></pre>
<?php
require_once plugin_dir_path( __FILE__ ) . 'meta-box-field-ruleset.php';
$nr=0;
foreach ($rulesets as $ruleset) {
render_meta_box_shipping_rules_single_ruleset ($post, ++$nr, $ruleset);
}
?>
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
// $( '.shipping_rules .chzn-select' ).chosen();
$('.shipping_rules .select2').select2();
});
</script>
<p class="shipping_rules_add"><a class='button ruleset-add' href='javascript:void(0);'><?php _e( 'Add a new ruleset', 'opentools-shippingrules' ); ?></a></p>
<?php
}
<?php
/**
* Shipping By Rules meta box settings.
*
* Display the shipping settings in the meta box.
*
* @author Reinhold Kainhofer
* @package OpenTools Shipping by Rules for WooCommerce
* @version 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
wp_nonce_field( 'rules_shipping_settings_meta_box', 'rules_shipping_settings_meta_box_nonce' );
global $post;
$settings = get_post_meta( $post->ID, '_rules_shipping_shipping_method', true );
$settings['shipping_title'] = ! empty( $settings['shipping_title'] ) ? $settings['shipping_title'] : '';
?><div class='rules_shipping rules_shipping_settings rules_shipping_meta_box rules_shipping_settings_meta_box'>
<p class='rules_shipping-option'>
<label for='shipping_title'><?php _e( 'Shipping title', 'woocommerce-advanced-free-shipping' ); ?></label>
<input type='text' class='' id='shipping_title' name='_rules_shipping_shipping_method[shipping_title]'
value='<?php echo esc_attr( $settings['shipping_title'] ); ?>' placeholder='<?php _e( 'e.g. Free Shipping', 'woocommerce-advanced-free-shipping' ); ?>'>
</p>
</div>
<?php
/**
* Shipping By Rules Shipping Method
* http://open-tools.net/woocommerce/
* Define Shipping cost by very general and flexible (text-based) rules.
* Ver. 1.0.0
* Author: Open Tools, Reinhold Kainhofer
* License: GPLv3+
*/
class WC_Shipping_by_Rules extends WC_Shipping_Method {
protected $helper = null;
/**
* Constructor for your shipping class
*
* @access public
* @return void
*/
public function __construct() {
if (!class_exists("RulesShippingFrameworkWooCommerce")) {
require_once( plugin_dir_path( __FILE__ ) . '/rules_shipping_framework_woocommerce.php');
}
$this->helper = RulesShippingFrameworkWooCommerce::getHelper();
$this->shipping_rules_option = 'woocommerce_shipping_rules_ordering';
$this->id = 'shipping_by_rules'; // Id for your shipping method. Should be uunique.
$this->title = $this->helper->__( 'Shipping By Rules <small>(displayed title changes according to configured methods)</small>');
$this->method_title = $this->helper->__( 'Shipping by Rules' ); // Title shown in admin
$this->method_description = $this->helper->__( 'Define shipping costs by general, text-based rules.' ); // Description shown in admin
$this->init();
}
/**
* Init your settings
*
* @access public
* @return void
*/
function init() {
// $this->get_rule_shipping_methods();
$this->init_form_fields();
$this->init_settings();
$this->enabled = $this->get_option ('enabled');
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_shipping_rules_sorting' ) );
}
/**
* get_shipping_rules_methods function.
*/
public function get_rule_shipping_methods() {
$unsortedmethods = get_posts (array ('posts_per_page' => '-1', 'post_type' => 'shipping_rules'));
$ordering = get_option( $this->shipping_rules_option );
$methods = array();
foreach ($ordering as $o) {
foreach ($unsortedmethods as $key=>$m) {
if ($m->ID == $o) {
$methods[$o] = $m;
unset($unsortedmethods[$key]);
break;
}
}
}
$methods = $methods + $unsortedmethods;
return $methods;
}
/**
* Initialise Gateway Settings Form Fields
*
* @access public
* @return void
*/
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'type' => 'checkbox',
'label' => $this->helper->__( 'Enable Shipping By Rules'),
'default' => 'yes'
),
'methods' => array(
'type' => 'rules_shipping_methods',
),
);
}
/**
* generate_additional_costs_html function.
*
* @access public
* @return string
*/
public function generate_rules_shipping_methods_html() {
ob_start();
include plugin_dir_path( __FILE__ ) . 'admin/html/html-shipping-methods.php';
return ob_get_clean();
}
/**
* validate_rules_shipping_methods_field function.
* Table does not need validation, so always return false.
*
* @access public
* @param mixed $key
* @return bool
*/
public function validate_rules_shipping_methods_field( $key ) {
return false;
}
/**
* Handle shipping rules settings
*/
public function process_shipping_rules_sorting() {
$ordering = isset($_POST[ 'rules_method_order']) ? array_map( 'wc_clean', $_POST[ 'rules_method_order'] ) : array();
update_option( $this->shipping_rules_option, $ordering );
$this->get_rule_shipping_methods();
}
/**
* calculate_shipping function.
*
* @access public
* @param mixed $package
* @return void
*/
public function calculate_shipping( $package ) {
$cost = $this->helper->getCosts($package, $this);
// TODO!
// print("<pre>Helper: ".print_r($helper,1)."</pre>");
// print($t);
// $rate = array(
// 'id' => $this->id,
// 'label' => "Test rule",
// 'cost' => '11.99',
// 'calc_tax' => 'per_item'
// );
// Register the rate
// $this->add_rate( $rate );
}
}
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Class rules_shipping_post_type.
*
* Initialize the Shipping by Rules post type (to configure the .
*
* @class
* @author Reinhold Kainhofer
* @package WooCommerce (Advanced) Shipping By Rules
* @version 1.0.0
* @license GPL v3+
* @copyright (c) 2015 Reinhold Kainhofer, Open Tools
* Based in part on WAFS_post_type (WooCommerce Advanced Free Shipping plugin)
* (C) Jeroen Sormani, Licensed under the GPL V3+
*/
/*global $notices;
$notices = array();
function my_add_notice($message, $type) {
global $notices;
$notices[] = array('type'=>$type, 'message'=>$message);
}
function print_notices() {
global $notices;
?>
<div class="error"><pre><?php print_r($notices); ?></pre></div>
<?php
foreach ($notices as $msg) {
file_put_contents("/vagrant/httpdocs/test.log",$msg['message'], FILE_APPEND);
?>
<div class="updated">
<p><?php echo $msg["message"]; ?></p>
</div>
<?php
}
$notices = array();
}
add_action('admin_notices', 'print_notices');
*/
class Shipping_Rules_post_type {
/**
* Constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Register post type
add_action( 'init', array( $this, 'shipping_rules_register_post_type' ) );
// Add/save meta boxes
add_action( 'add_meta_boxes_shipping_rules', array( $this, 'shipping_rules_post_type_meta_box' ) );
add_action( 'save_post_shipping_rules', array( $this, 'shipping_rules_save_meta' ) );
add_action( 'save_post_shipping_rules', array( $this, 'shipping_rules_save_rulesets_meta' ) );
// Edit user messages
add_filter( 'post_updated_messages', array( $this, 'shipping_rules_custom_post_type_messages' ) );
// Redirect after delete
add_action('load-edit.php', array( $this, 'shipping_rules_redirect_after_trash' ) );
// AJAX handling for the edit page:
add_action( 'wp_ajax_shipping_rules_add_ruleset', array( $this, 'shipping_rules_add_ruleset' ) );
}
/**
* Post type.
*
* Register 'shipping_rules' post type.
*
* @since 1.0.0
*/
public function shipping_rules_register_post_type() {
$labels = array(
'name' => __( 'Shipping By Rules Methods', 'opentools-shippingrules' ),
'singular_name' => __( 'Shipping By Rules method', 'opentools-shippingrules' ),
'add_new' => __( 'Add New', 'opentools-shippingrules' ),
'add_new_item' => __( 'Add New Shipping by Rules method', 'opentools-shippingrules' ),
'edit_item' => __( 'Edit Shipping by Rules method', 'opentools-shippingrules' ),
'new_item' => __( 'New Shipping by Rules method', 'opentools-shippingrules' ),
'view_item' => __( 'View Shipping by Rules method', 'opentools-shippingrules' ),
'search_items' => __( 'Search Shipping by Rules methods', 'opentools-shippingrules' ),
'not_found' => __( 'No Shipping by Rules methods', 'opentools-shippingrules' ),
'not_found_in_trash' => __( 'No Shipping by Rules methods found in Trash', 'opentools-shippingrules' ),
);
register_post_type( 'shipping_rules', array(
'label' => 'shipping_rules',
'show_ui' => true,
'show_in_menu' => false,
'public' => false,
'publicly_queryable' => false,
'capability_type' => 'post',
'map_meta_cap' => true,
'rewrite' => false,
'_builtin' => false,
'query_var' => true,
'supports' => array( 'title' ),
'labels' => $labels,
) );
}
/**
* Messages.
*
* Modify the notice messages text for the 'shipping_rules' post type.
*
* @since 1.0.0
*
* @param array $messages Existing list of messages.
* @return array Modified list of messages.
*/
function shipping_rules_custom_post_type_messages( $messages ) {
$post = get_post();
$post_type = get_post_type( $post );
$post_type_object = get_post_type_object( $post_type );
$messages['shipping_rules'] = array(
0 => '',
1 => __( 'Shipping by Rules method updated.', 'opentools-shippingrules' ),
2 => __( 'Custom field updated.', 'opentools-shippingrules' ),
3 => __( 'Custom field deleted.', 'opentools-shippingrules' ),
4 => __( 'Shipping by Rules method updated.', 'opentools-shippingrules' ),
5 => isset( $_GET['revision'] ) ?
sprintf( __( 'Shipping by Rules method restored to revision from %s', 'opentools-shippingrules' ), wp_post_revision_title( (int) $_GET['revision'], false ) )
: false,
6 => __( 'Shipping by Rules method published.', 'opentools-shippingrules' ),
7 => __( 'Shipping by Rules method saved.', 'opentools-shippingrules' ),
8 => __( 'Shipping by Rules method submitted.', 'opentools-shippingrules' ),
9 => sprintf(
__( 'Shipping by Rules method scheduled for: <strong>%1$s</strong>.', 'opentools-shippingrules' ),
date_i18n( __( 'M j, Y @ G:i', 'opentools-shippingrules' ), strtotime( $post->post_date ) )
),
10 => __( 'Shipping by Rules method draft updated.', 'opentools-shippingrules' ),
);
if ( 'shipping_rules' == $post_type ) :
$overview_link = admin_url( 'admin.php?page=wc-settings&tab=shipping&section=shipping_by_rules' );
$overview = sprintf( ' <a href="%s">%s</a>', esc_url( $overview_link ), __( 'Return to overview.', 'opentools-shippingrules' ) );
$messages[ $post_type ][1] .= $overview;
$messages[ $post_type ][6] .= $overview;
$messages[ $post_type ][9] .= $overview;
$messages[ $post_type ][8] .= $overview;
$messages[ $post_type ][10] .= $overview;
endif;
return $messages;
}
/**
* Add meta boxes.
*
* Add two meta boxes to the shipping_by_rules post type with rulesets and settings.
*
* @since 1.0.0
*/
public function shipping_rules_post_type_meta_box($post) {
// my_add_notice( "shipping_rules_post_type_meta_box called", 'info');
add_meta_box( 'shipping_rules_settings', __( 'Shipping settings', 'opentools-shippingrules' ), array( $this, 'render_shipping_rules_settings' ), 'shipping_rules', 'normal' );
add_meta_box(
/* ID */ 'shipping_rules_rulesets',
/* Title */ __( 'Rulesets', 'opentools-shippingrules' ),
/* Callback */array( $this, 'render_shipping_rulesets' ),
/* Screen */ 'shipping_rules',
/* Context */ 'advanced');
add_meta_box( 'shipping_rules_help', __( 'Overview of the Rules Syntax', 'opentools-shippingrules' ), array( $this, 'render_shipping_rules_help' ), 'shipping_rules', 'side' );
}
/**
* Render meta box.
*
* Render and display the rulesets meta box contents.
*
* @since 1.0.0
*/
public function render_shipping_rulesets($post, $metabox) {
require_once plugin_dir_path( __FILE__ ) . 'admin/settings/meta-box-rulesets.php';
$rulesets = get_post_meta( $post->ID, '_rules_shipping_ruleset', true );
// file_put_contents("/vagrant/httpdocs/test.log","render_shipping_rulesets called, id=$post->ID, rulesets=".print_r($rulesets,1)."\n\n\n\n\n", FILE_APPEND);
render_meta_box_shipping_rules_rulesets ($post, $rulesets);
}
/**
* Adding a rule set in the edit page via AJAX => simply return the block generated
*/
public function shipping_rules_add_ruleset() {
require_once plugin_dir_path( __FILE__ ) . 'admin/settings/meta-box-field-ruleset.php';
$nr = absint($_POST['rulesetnr']);
render_meta_box_shipping_rules_single_ruleset(null, $nr, null);
die();
}
/**
* Render meta box.
*
* Render and display the settings meta box.
*
* @since 1.0.0
*/
public function render_shipping_rules_settings() {
require_once plugin_dir_path( __FILE__ ) . 'admin/settings/meta-box-settings.php';
}
/**
* Render meta box.
*
* Render and display the help meta box.
*
* @since 1.0.0
*/
public function render_shipping_rules_help() {
require_once plugin_dir_path( __FILE__ ) . 'admin/settings/meta-box-help.php';
}
/**
* Save rulesets meta box.
*
* Validate and save post meta from rulesets meta box.
*
* @since 1.0.0
*/
public function shipping_rules_save_rulesets_meta( $post_id ) {
// my_add_notice( "shipping_rules_save_rulesets_meta called", 'info');
// file_put_contents("/vagrant/httpdocs/test.log","shipping_rules_save_rulesets_meta called, id=$post_id\n", FILE_APPEND);
if ( ! isset( $_POST['shipping_rules_rulesets_meta_box_nonce'] ) || ! wp_verify_nonce( $_POST['shipping_rules_rulesets_meta_box_nonce'], 'shipping_rules_rulesets_meta_box' ) ) :
return $post_id;
endif;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) :
return $post_id;
endif;
if ( ! current_user_can( 'manage_woocommerce' ) ) :
return $post_id;
endif;
// file_put_contents("/vagrant/httpdocs/test.log","shipping_rules_save_rulesets_meta, id=$post_id, checks passed\n", FILE_APPEND);
$shipping_method_rulesets = $_POST['_rules_shipping_ruleset'];
$shipping_method_ordering = $_POST['_rules_shipping_ordering'];
// file_put_contents("/vagrant/httpdocs/test.log","shipping_rules_save_rulesets_meta, id=$post_id, ordering: ".print_r($shipping_method_ordering,1)."\n\n\n\n", FILE_APPEND);
// file_put_contents("/vagrant/httpdocs/test.log","shipping_rules_save_rulesets_meta, id=$post_id, ruleset: ".print_r($shipping_method_rulesets,1)."\n\n\n\n", FILE_APPEND);
$rulesets = array();
foreach ($shipping_method_ordering as $o) {
$rulesets[] = $shipping_method_rulesets[$o];
}
file_put_contents("/vagrant/httpdocs/test.log","shipping_rules_save_rulesets_meta, id=$post_id, Sorted rulesets: ".print_r($shipping_method_rulesets,1)."\n\n\n\n", FILE_APPEND);
update_post_meta( $post_id, '_rules_shipping_ruleset', $rulesets );
}
/**
* Save settings meta box.
*
* Validate and save post meta from settings meta box.
*
* @since 1.0.0
*/
public function shipping_rules_save_meta( $post_id ) {
// my_add_notice( "shipping_rules_save_meta called", 'info');
if ( ! isset( $_POST['shipping_rules_settings_meta_box_nonce'] ) || ! wp_verify_nonce( $_POST['shipping_rules_settings_meta_box_nonce'], 'shipping_rules_settings_meta_box' ) ) :
return $post_id;
endif;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) :
return $post_id;
endif;
if ( ! current_user_can( 'manage_woocommerce' ) ) :
return $post_id;
endif;
// Store general settings
// $shipping_method = array_map( 'sanitize_text_field', $_POST['_shipping_rules_shipping_method'] );
// update_post_meta( $post_id, '_shipping_rules_shipping_method', $shipping_method );
}
/**
* Redirect trash.
*
* Redirect user after trashing a shipping_by_rules post.
*
* @since 1.0.0
*/
public function shipping_rules_redirect_after_trash() {
$screen = get_current_screen();
if( 'edit-shipping_rules' == $screen->id ) :
if( isset( $_GET['trashed'] ) && intval( $_GET['trashed'] ) > 0 ) :
wp_redirect( admin_url( '/admin.php?page=wc-settings&tab=shipping&section=shipping_by_rules' ) );
exit();
endif;
endif;
}
}
<?php
/**
* Shipping by Rules generic helper class (Joomla/VM-specific)
* Reinhold Kainhofer, Open Tools, office@open-tools.net
* @copyright (C) 2012-2015 - Reinhold Kainhofer
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
**/
if ( !defined( 'ABSPATH' ) ) {
die( 'Direct Access to ' . basename( __FILE__ ) . ' is not allowed.' );
}
require_once( plugin_dir_path( __FILE__ ) . '/../library/rules_shipping_framework.php');
class RulesShippingFrameworkWooCommerce extends RulesShippingFramework {
function _construct() {
parent::_construct();
load_plugin_textdomain('opentools-shippingrules', false, basename( dirname( __FILE__ ) ) . '/languages' );
}
static function getHelper() {
static $helper = null;
if (!$helper) {
$helper = new RulesShippingFrameworkWooCommerce();
$helper->setup();
}
return $helper;
}
function urlPath($type, $file) {
return plugins_url('library/' . $type . '/' . $file, __FILE__);
}
function getCustomFunctions() {
// Let other plugins add custom functions!
// The onVmShippingRulesRegisterCustomFunctions() trigger is expected to return an array of the form:
// array ('functionname1' => 'function-to-be-called',
// 'functionname2' => array($classobject, 'memberfunc')),
// ...);
return apply_filters( 'opentools_shipping_by_rules_replacements', array());
}
protected function printWarning($message) {
// Keep track of warning messages, so we don't print them twice:
global $printed_warnings;
if (!isset($printed_warnings))
$printed_warnings = array();
if (!in_array($message, $printed_warnings)) {
wc_add_notice( $message, 'error');
$printed_warnings[] = $message;
}
}
/** @tag public-api
* @function debug()
* Print a debug message (untranslated) in the system-specific way.
* @param $message the debug message to be printed
*/
public function debug($message) {
if ( true === WP_DEBUG ) {
if ( is_array( $message ) || is_object( $message ) ) {
error_log( print_r( $message, true ) );
} else {
error_log( $message );
}
}
}
/**
* HELPER FUNCTIONS, WooCommerce-specific
*/
public function __($string) {
$args = func_get_args();
$string = $this->readableString($string);
$string = __($string, 'opentools-shippingrules');
if (count($args)>1) {
$args[0] = $string;
return call_user_func_array("sprintf", $args);
} else {
return $string;
}
}
protected function setMethodCosts($method, $match, $costs) {
// Allow some system-specific code, e.g. setting some members of $method, etc.
$title = $method->title;
if ($match["rule_name"]) {
$title .= " (".$match["rule_name"].")";
}
$rate = array(
'id' => $method->id,
'label' => $title,
'cost' => $costs,
// 'calc_tax' => 'per_item'
);
// Register the rate
$this->add_rate( $rate );
}
protected function getCartProducts($package, $method) {
return $package['contents'];
}
protected function getMethodId($method) {
return $method->id;
}
protected function getMethodName($method) {
// Shall we use title or method_title?
return $method->title;
}
protected function parseMethodRules (&$method) {
if (!isset($method->settings) || !isset($method->settings->rulesets)) {
return;
}
foreach ($method->settings->rulesets as $ruleset) {
$this->parseMethodRule($ruleset->rule,
$method->countries /* TODO: or use a custom setting of $ruleset? */,
array(),
$method);
}
}
/**
* Functions to calculate the cart variables:
* - getOrderCounts($cart, $products, $method)
* - getOrderDimensions
*/
/** Functions to calculate all the different variables for the given cart and given (sub)set of products in the cart */
protected function getOrderCounts ($cart, $products, $method) {
$counts = array('products' => count($products));
$articles = 0;
foreach ($products as $product) {
$articles += $product['quantity'];
}
$counts['articles'] = $articles;
return $counts;
}
protected function getOrderDimensions ($cart, $products, $method) {
/* Cache the value in a static variable and calculate it only once! */
$dimensions=array(
'volume' => 0,
'maxvolume' => 0, 'minvolume' => 99999999,
'maxlength' => 0, 'minlength' => 99999999, 'totallength' => 0,
'maxwidth' => 0, 'minwidth' => 99999999, 'totalwidth' => 0,
'maxheight' => 0, 'minheight' => 99999999, 'totalheight' => 0,
);
foreach ($products as $product) {
$l = $product['data']->length;
$w = $product['data']->width;
$h = $product['data']->height;
$volume = $l * $w * $h;
$dimensions['volume'] += $volume * $product['quantity'];
$dimensions['maxvolume'] = max ($dimensions['maxvolume'], $volume);
$dimensions['minvolume'] = min ($dimensions['minvolume'], $volume);
$dimensions['totallength'] += $l * $product['quantity'];
$dimensions['maxlength'] = max ($dimensions['maxlength'], $l);
$dimensions['minlength'] = min ($dimensions['minlength'], $l);
$dimensions['totalwidth'] += $w * $product['quantity'];
$dimensions['maxwidth'] = max ($dimensions['maxwidth'], $w);
$dimensions['minwidth'] = min ($dimensions['minwidth'], $w);
$dimensions['totalheight'] += $h * $product['quantity'];
$dimensions['maxheight'] = max ($dimensions['maxheight'], $h);
$dimensions['minheight'] = min ($dimensions['minheight'], $h);
}
return $dimensions;
}
protected function getOrderWeights ($cart, $products, $method) {
$dimensions=array(
'weight' => 0,
'maxweight' => 0, 'minweight' => 9999999999,
);
foreach ($products as $product) {
$w = $product['data']->get_weight();
$dimensions['maxweight'] = max ($dimensions['maxweight'], $w);
$dimensions['minweight'] = min ($dimensions['minweight'], $w);
$dimensions['weight'] += $w * $product['quantity'];
}
return $dimensions;
}
protected function getOrderListProperties ($cart, $products, $method) {
$categories = array();
$skus = array();
$tags = array();
$shipping_classes = array();
foreach ($products as $product) {
$id = $product['data']->id;
if ($product['data']->get_sku()) {
$skus[] = $product['data']->get_sku();
}
foreach (wc_get_product_terms( $id, 'product_cat') as $c) {
$categories[] = $c->slug;
}
foreach (wc_get_product_terms( $id, 'product_tag') as $c) {
$tags[] = $c->slug;
}
$shipclass = $product['data']->get_shipping_class();
if ($shipclass) {
$shipping_classes[] = $shipclass;
}
}
$skus = array_unique($skus);
$categories = array_unique($categories);
$tags = array_unique($tags);
$shipping_classes = array_unique($shipping_classes);
return array (
'skus' => $skus,
'categories' => $categories,
'tags' => $tags,
'shippingclasses' => $shipping_classes,
'coupons' => $cart['applied_coupons'],
);
}
protected function getOrderAddress ($cart, $method) {
$address = $cart['destination'];
$zip = isset($address['postcode'])?trim($address['postcode']):'';
$data = array(
'zip' => $zip,
'postcode' => $zip,
'zip1' => substr($zip,0,1),
'zip2' => substr($zip,0,2),
'zip3' => substr($zip,0,3),
'zip4' => substr($zip,0,4),
'zip5' => substr($zip,0,5),
'zip6' => substr($zip,0,6),
'city' => trim($address['city']),
'country' => trim($address['country']),
'state' => trim($address['state']),
'address1' => trim($address['address']),
'address2' => trim($address['address_2']),
);
/* Get the user from the package information and extract further information about the buyer */
$user = $cart['user'];
// TODO: Extract user!
/** $data['company'] = isset($address['company'])?$address['company']:'';
$data['title'] = isset($address['title'])?$address['title']:'';
$data['first_name'] = isset($address['title'])?$address['title']:'';
$data['middle_name'] = isset($address['middle_name'])?$address['middle_name']:'';
$data['last_name'] = isset($address['last_name'])?$address['last_name']:'';
$data['phone1'] = isset($address['phone_1'])?$address['phone_1']:'';
$data['phone2'] = isset($address['phone_2'])?$address['phone_2']:'';
$data['fax'] = isset($address['fax'])?$address['fax']:'';
$data['email'] = isset($address['email'])?$address['email']:'';
*/
return $data;
}
protected function getOrderPrices ($cart, $products, /*$cart_prices, */$method) {
$data = array(
'total' => 0,
'subtotal' => 0,
'taxtotal' => 0,
'taxsubtotal' => 0,
'cost' => 0,
);
// Calculate the prices from the individual products!
// Possible problems are discounts on the order total
foreach ($products as $product) {
$data['total'] += $product['line_total'];
$data['subtotal'] += $product['line_subtotal'];
$data['taxtotal'] += $product['line_tax'];
$data['taxsubtotal'] += $product['line_subtotal_tax'];
$data['cost'] += $product['line_total'] + $product['line_tax'];
}
$data['amount'] = $data['cost'];
$data['amountwithtax'] = $data['cost'];
return $data;
}
/** Allow child classes to add additional variables for the rules or modify existing one
*/
protected function addCustomCartValues ($cart, $products, $method, &$values) {
}
protected function addPluginCartValues($cart, $products, $method, &$values) {
return apply_filters( 'opentools_shipping_by_rules_get_cart_values', array(&$cartvals, $cart, $products, $method));
}
/** Filter the given array of products and return only those that belong to the categories, manufacturers,
* vendors or products given in the $filter_conditions. The $filter_conditions is an array of the form:
* array( 'skus'=>array(....), 'categories'=>array(1,2,3,42), 'manufacturers'=>array(77,78,83), 'vendors'=>array(1,2))
* Notice that giving an empty array for any of the keys means "no restriction" and is exactly the same
* as leaving out the entry altogether
*/
public function filterProducts($products, $filter_conditions) {
$result = array();
foreach ($products as $p) {
if (!empty($filter_conditions['skus']) && !in_array($p['data']->get_sku(), $filter_conditions['skus']))
continue;
if (!empty($filter_conditions['categories']) && count(array_intersect($filter_conditions['categories'], $p['data']->get_categories())==0))
continue;
$result[] = $p;
}
return $result;
}
}
This diff is collapsed.
=== WooCommerce Basic Ordernumbers ===
Contributors: opentools
Tags: WooCommerce, Order numbers, orders
Requires at least: 4.0
Tested up to: 4.1.1
Stable tag: trunk
License: GPLv3 or later
License URI: http://www.gnu.org/licenses/gpl.html
Customize order numbers for WooCommerce. The order numbers can contain arbitrary text, a running counter and the current year.
== Description ==
The most flexible and complete solution for your WooCommerce webshop to customize your order numbers!
By default, WooCommerce uses the WordPress post ID of the order, which result in gaps between the order numbers. With this plugin you can configure the order numbers to have consecutive counters. Furthermore, the order number can contain the year, and the counter can be configured to reset each year.
The number format is a simple string, where # indicates the counter and [year] or [year2] indicate the year.
To get order numbers like "WC-2015-1", "WC-2015-2", etc., simply set the format to "WC-[year]-#".
The plugin comes in two flavors:
* This **free basic version**, which provides **sequential numbers** and allows the **year in the order number**
* The **paid advanced version**, with lots of **additional features**:
* Counter formatting: initial value, counter increments, number padding
* Lots of variables to be used in the formats
- date/time: year, month, day, hour, etc.
- address: customer country, zip, name, etc.
- order-specific: Number of articles, products, order total etc.
- product categories, shipping method
* Custom variable definitions (with conditions on available variables)
* Multiple concurrent counters (e.g. numbering per country, per day, per ZIP, ...)
* Different order numbers for free orders (e.g. "FREE-01" for free orders)
* Different number format for e.g. certain IP addresses (for testing)
* Different number format depending on products, product categories, shipping classes
* Customize invoice numbers (only for the "WooCommerce PDF Invoices and Package Slips" plugin)
For the full documentation of both the basic and the advanced ordernumbers plugin for WooCommerce, see:
http://open-tools.net/documentation/advanced-order-numbers-for-woocommerce.html
== Installation ==
1. To install the plugin, either:
1. use WordPress' plugin manager to find it in the WordPress plugin directory and directly install it from the WP plugin manager, or
1. use WordPress' plugin manager to upload the plugin's zip file.
1. After installation, activate the plugin through the 'Plugins' menu in WordPress
1. Enable the plugin's functionality in the WooCommerce settings (tab "Checkout" -> "Order numbers")
== Frequently Asked Questions ==
= How can I create nice order numbers for existing orders? =
This plugin is intended for future orders. You can, however, create order numbers for existing orders in the order view in the WordPress admin section. In the top right "Order Actions" box select "Assign a new order number" and click "Save Order". Notice, however, that this will create an order number as if the order was created at that very moment.
= What about invoice numbers? =
The Advanced Ordernumbers for WooCommerce plugin supports some invoicing plugins. This functionality is not available in the free version, though.
== Screenshots ==
1.
== Changelog ==
= 1.0 =
* Initial release
== Upgrade Notice ==
To install the Advanced Ordernumbers for WooCommerce package, proceed as described in the Installation section.
No upgrades yet.
=== WooCommerce Basic Ordernumbers ===
Contributors: opentools
Tags: WooCommerce, Order numbers, orders
Requires at least: 4.0
Tested up to: 4.2.2
Stable tag: 1.1
License: GPLv3 or later
License URI: http://www.gnu.org/licenses/gpl.html
Customize order numbers for WooCommerce. The order numbers can contain arbitrary text and a running counter.
== Description ==
The most flexible and complete solution for your WooCommerce webshop to customize your order numbers!
By default, WooCommerce uses the WordPress post ID of the order, which result in gaps between the order numbers. With this plugin you can configure the order numbers to have consecutive counters. Furthermore, the order number can contain the year, and the counter can be configured to reset each year.
The number format is a simple string, where # indicates the counter.
To get order numbers like "WC-376", "WC-377", "WC-378", etc., simply set the format to "WC-#".
The plugin comes in two flavors:
* This **free basic version**, which provides **sequential numbers** and allows arbitrary text (prefix / postfix) in the numbers
* The **paid advanced version**, with lots of **additional features**:
* Counter __formatting__: initial value, counter increments, number padding
* Flexible __counter resets__
* Lots of __variables__ to be used in the formats
- date/time: year, month, day, hour, etc.
- address: customer country, zip, name, etc.
- order-specific: Number of articles, products, order total etc.
- product categories, shipping method
* Custom variable definitions (with conditions on available variables)
* Multiple concurrent counters (e.g. numbering per country, per day, per ZIP, ...)
* Different order numbers for free orders (e.g. "FREE-01" for free orders)
* Different number format for e.g. certain IP addresses (for testing)
* Different number format depending on products, product categories, shipping classes
* Customize invoice numbers (only for the "WooCommerce PDF Invoices and Package Slips" plugin)
For the full documentation of both the basic and the advanced ordernumbers plugin for WooCommerce, see:
http://open-tools.net/documentation/advanced-order-numbers-for-woocommerce.html
== Installation ==
1. To install the plugin, either:
1. use WordPress' plugin manager to find it in the WordPress plugin directory and directly install it from the WP plugin manager, or
1. use WordPress' plugin manager to upload the plugin's zip file.
1. After installation, activate the plugin through the 'Plugins' menu in WordPress
1. Enable the plugin's functionality in the WooCommerce settings (tab "Checkout" -> "Order numbers")
== Frequently Asked Questions ==
= How can I create nice order numbers for existing orders? =
This plugin is intended for future orders. You can, however, create order numbers for existing orders in the order view in the WordPress admin section. In the top right "Order Actions" box select "Assign a new order number" and click "Save Order". Notice, however, that this will create an order number as if the order was created at that very moment.
= How can I start the counter at a value higher than 1? =
The easiest way is to configure the plugin, make one test order and then modify the counter in the plugin configuration to the value you desire.
= What about invoice numbers? =
The Advanced Ordernumbers for WooCommerce plugin supports some invoicing plugins. This functionality is not available in the free version, though.
== Screenshots ==
== Changelog ==
= 1.1 =
* Some smaller bugfixes
* Removed variable definition for year
= 1.0 =
* Initial release
== Upgrade Notice ==
To install the Advanced Ordernumbers for WooCommerce package, proceed as described in the Installation section.
No upgrades yet.
<?php
/**
* Plugin Name: Shipping By Rules
* Plugin URI: http://open-tools.net/woocommerce/
* Description: Define Shipping cost by very general and flexible (text-based) rules.
* Version: 1.0.0
* Author: Open Tools, Reinhold Kainhofer
* Author URI: http://open-tools.net
* Text Domain: woocommerce-shipping-by-rules
* Domain Path:
* License: GPL2+
* WC requires at least: 2.2
* WC tested up to: 2.3
* Copyright (C) 2015 Reinhold Kainhofer
*
* This file is part of WooCommerce Shipping By Rules,
* a plugin for WordPress and WooCommerce.
*
* WooCommerce Shipping By Rules is free software:
* You can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WordPress. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Class WooCommerce_Shipping_By_Rules.
*
* Main Shipping by Rules class, add filters and handling all other files.
*
* @class WooCommerce_Shipping_By_Rules
* @version 1.0.0
* @author Reinhold Kainhofer
*/
class WooCommerce_Shipping_By_Rules {
/**
* Version.
*
* @since 1.0.0
* @var string $version Plugin version number.
*/
public $version = '1.0.0';
/**
* Instance of WooCommerce_Shipping_By_Rules.
*
* @since 1.0.0
* @access private
* @var object $instance The instance of WooCommerce_Shipping_By_Rules.
*/
private static $instance;
/**
* Constructor.
*
* @since 1.0.0
*/
public function __construct() {
if ( ! function_exists( 'is_plugin_active_for_network' ) )
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
// Check if WooCommerce is active
if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) :
if ( ! is_plugin_active_for_network( 'woocommerce/woocommerce.php' ) ) :
return;
endif;
endif;
$this->init();
}
/**
* Instance.
*
* An global instance of the class. Used to retrieve the instance
* to use on other files/plugins/themes.
*
* @since 1.0.0
*
* @return object Instance of the class.
*/
public static function instance() {
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Init.
*
* Initialize plugin parts.
*
* @since 1.0.0
*/
public function init() {
// Add hooks/filters
$this->hooks();
// Load textdomain
$this->load_textdomain();
// Updater
$this->update();
/**
* Require file with shipping_by_rules post type definition.
*/
require_once plugin_dir_path( __FILE__ ) . 'includes/rules-shipping-post-type.php';
$this->post_type = new Shipping_Rules_post_type();
}
/**
* Update.
*
* Runs when the plugin is updated and checks if there should be
* any data updated to be compatible for the new version.
*
* @since 1.0.0
*/
public function update() {
$db_version = get_option( 'shipping_by_rules_plugin_version', '1.0.0' );
// Stop current version is up to date
if ( $db_version >= $this->version ) :
return;
endif;
// Update functions come here:
// From version 1.x.x to 1.x.y
// From version 1.x.y to 1.x.z
update_option( 'shipping_by_rules_plugin_version', $this->version );
}
/**
* Hooks.
*
* Initialize all class hooks.
*
* @since 1.0.0
*/
public function hooks() {
// Initialize shipping method class
add_action( 'woocommerce_shipping_init', array( $this, 'shipping_by_rules_init' ) );
// Add shipping method
add_action( 'woocommerce_shipping_methods', array( $this, 'shipping_by_rules_add_shipping_method' ) );
// Enqueue scripts
add_action( 'admin_enqueue_scripts', array( $this, 'shipping_by_rules_admin_enqueue_scripts' ) );
}
/**
* Textdomain.
*
* Load the textdomain based on WP language.
*
* @since 1.0.0
*/
public function load_textdomain() {
// Load textdomain
load_plugin_textdomain('opentools-shippingrules', false, basename( dirname( __FILE__ ) ) . '/languages' );
}
/**
* Shipping method.
*
* Include the WooCommerce shipping method class.
*
* @since 1.0.0
*/
public function shipping_by_rules_init() {
require_once plugin_dir_path( __FILE__ ) . 'includes/rules-shipping-method.php';
$this->was_method = new WC_Shipping_by_Rules();
}
/**
* Add shipping method.
*
* Add shipping method to WooCommerce.
*
* @since 1.0.0
*/
public function shipping_by_rules_add_shipping_method( $methods ) {
if ( class_exists( 'WC_Shipping_by_Rules' ) ) :
$methods[] = 'WC_Shipping_by_Rules';
endif;
// TODO: Figure out a way to add each shipping by rules method as a
// separate WooCommerce shipping method (ie. their order can be
// defined in the WC configuration and not only in the Shipping by
// Rules Method configuration screen.
return $methods;
}
/**
* Enqueue scripts.
*
* Enqueue javascript and stylesheets to the admin area.
*
* @since 1.0.0
*/
public function shipping_by_rules_admin_enqueue_scripts() {
// For some strange reason, WC does not define the select2.css style...
$assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/';
wp_enqueue_style( 'select2', $assets_path . 'css/select2.css' );
// wp_enqueue_style( 'chosen', $assets_path . 'css/chosen.css' );
wp_enqueue_style( 'shipping_by_rules-style', plugins_url( 'assets/css/admin-styles.css', __FILE__ ), array('select2'), $this->version );
wp_enqueue_script( 'shipping-by-rules-config', plugins_url( 'assets/js/shipping-by-rules-config.js', __FILE__ ), array( 'jquery', 'jquery-ui-sortable', 'select2', 'wc-enhanced-select' ), $this->version, true );
}
}
/**
* The main function responsible for returning the WooCommerce_Shipping_By_Rules object.
*
* Use this function like you would a global variable, except without needing to declare the global.
*
* Example: <?php OpenTools_ShippingByRules()->method_name(); ?>
*
* @since 1.0.0
*
* @return object WooCommerce_Shipping_By_Rules class object.
*/
if ( ! function_exists( 'Shipping_By_Rules' ) ) :
function OpenTools_ShippingByRules() {
return WooCommerce_Shipping_By_Rules::instance();
}
endif;
OpenTools_ShippingByRules();
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment