<?php
/*
Plugin Name: WooCommerce Price per product shipping method.
Plugin URI: http://www.weknowit.nu
Description: A shipping method for WooCommerce to set shipping price based on number of articles.
Version: 1.0
Author: Daniel Holm, <daniel.holm@weknowit.nu>
Author URI: http://www.danielholm.se
License: GPL2
*/
/* Copyright 2013 Daniel Holm (email : daniel.holm@weknowit.nu)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// Make sure WooCommerce is active
if ( in_array( 'woocommerce/woocommerce.php', get_option( 'active_plugins' ) ) ) {
add_filter( 'woocommerce_shipping_methods', 'add_shippin_per_product_method' );
}
add_action( 'woocommerce_init', 'load_my_shipping_class' );
function load_my_shipping_class() {
/**
* Price per product shipping method.
*
* @class WC_Shipping_Per_Product
* @version 1.0
* @author Daniel Holm, We Know IT
*/
class WC_Shipping_Per_Product extends WC_Shipping_Method {
// construct function.
function __construct() {
$this->id = 'per_product';
$this->method_title = __( 'Price Per Product', 'woocommerce' );
$this->init();
}
// run on init
function init() {
// load settings
$this->init_form_fields();
$this->init_settings();
// define variables
$this->enabled = true;
$this->title = $this->get_option( 'title' );
$this->minfee = $this->get_option( 'minfee' );
$this->fee = $this->get_option( 'fee' );
$this->codes = $this->get_option( 'codes' );
$this->availability = $this->get_option( 'availability' );
$this->countries = $this->get_option( 'countries' );
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
} // end of init
function init_form_fields() {
global $woocommerce;
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable Per Product Method', 'woocommerce' ),
'default' => 'no'
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => __( 'Per Product', 'woocommerce' ),
'desc_tip' => true,
),
'minfee' => array(
'title' => __( 'Delivery Fee for Single product', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
),
'description' => __( 'What fee do you want to charge for just one product. Leave blank to disable, 0 to for free.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => '0.00'
),
'fee' => array(
'title' => __( 'Delivery Fee', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
),
'description' => __( 'What fee do you want to charge for local delivery, disregarded if you choose free. Leave blank to disable.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => '0.00'
),
'codes' => array(
'title' => __( 'Zip/Post Codes', 'woocommerce' ),
'type' => 'textarea',
'description' => __( 'What zip/post codes would you like to offer delivery to? Separate codes with a comma. Accepts wildcards, e.g. P* will match a postcode of PE30.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => '12345, 56789 etc'
),
'availability' => array(
'title' => __( 'Method availability', 'woocommerce' ),
'type' => 'select',
'default' => 'all',
'class' => 'availability',
'options' => array(
'all' => __( 'All allowed countries', 'woocommerce' ),
'specific' => __( 'Specific Countries', 'woocommerce' )
)
),
'countries' => array(
'title' => __( 'Specific Countries', 'woocommerce' ),
'type' => 'multiselect',
'class' => 'chosen_select',
'css' => 'width: 450px;',
'default' => '',
'options' => $woocommerce->countries->countries
)
);
} // end of forms init
// show admin options
function admin_options() {
global $woocommerce; ?>
<h3><?php echo $this->method_title; ?></h3>
<p><?php _e( 'Per product is a method to set a price per product for delivery.', 'woocommerce' ); ?></p>
<table class="form-table">
<?php $this->generate_settings_html(); ?>
</table>
<?php
}
// calculate shipping cost
function calculate_shipping( $package = array() ) {
global $woocommerce;
$shipping_total = 0;
$fee = ( trim( $this->fee ) == '' ) ? 0 : $this->fee;
$total_items = sprintf(_n('%d', '%d', $woocommerce->cart->cart_contents_count, 'woothemes'), $woocommerce->cart->cart_contents_count);
//print "This many: ".$total_items;
if ( $total_items > 1 ) {
$shipping_total += $this->fee * $total_items;
}
else {
$shipping_total += $this->minfee;
}
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => $shipping_total
);
$this->add_rate($rate);
} //end of shipping calc
function is_available( $package ) {
global $woocommerce;
if ($this->enabled=="no") return false;
// If post codes are listed, let's use them.
$codes = '';
if ( $this->codes != '' ) {
foreach( explode( ',', $this->codes ) as $code ) {
$codes[] = $this->clean( $code );
}
}
if ( is_array( $codes ) ) {
$found_match = false;
if ( in_array( $this->clean( $package['destination']['postcode'] ), $codes ) )
$found_match = true;
// Wildcard search
if ( ! $found_match ) {
$customer_postcode = $this->clean( $package['destination']['postcode'] );
$customer_postcode_length = strlen( $customer_postcode );
for ( $i = 0; $i <= $customer_postcode_length; $i++ ) {
if ( in_array( $customer_postcode, $codes ) )
$found_match = true;
$customer_postcode = substr( $customer_postcode, 0, -2 ) . '*';
}
}
if ( ! $found_match )
return false;
}
// Yay! We passed!
return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', true );
}
} // end of class
// add the new shipment class
function add_shippin_per_product_method( $methods ) {
// Class definition
include( 'class-wc-shipping-per-product.php' );
$methods[] = 'WC_Shipping_Per_Product';
return $methods;
}
}