Skip to content

Instantly share code, notes, and snippets.

@goranefbl
Last active July 2, 2024 11:01
Show Gist options
  • Save goranefbl/1c4bb045e8a063980ef8 to your computer and use it in GitHub Desktop.
Save goranefbl/1c4bb045e8a063980ef8 to your computer and use it in GitHub Desktop.
Adds a new shipping method that calculates shipping price based on quantity of products
<?php
/*
Plugin Name: Shipping Price per Quantity Plugin
Plugin URI: http://itsgoran.com
Description: Adds a new shipping method that calculates shipping price based on quantity of products - made for Cider.
Version: 1.0.0
Author: Goran Jakovljevic
Author URI: http://itsgoran.com
*/
/**
* Check if WooCommerce is active
*/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
function cider_shipping_method_init() {
if ( ! class_exists( 'Cider_Shipping_Method' ) ) {
class Cider_Shipping_Method extends WC_Shipping_Method {
/**
* Constructor for your shipping class
*
* @access public
* @return void
*/
public function __construct() {
$this->id = 'cider_shipping_method'; // Id for your shipping method. Should be uunique.
$this->method_title = __( 'Shipping Price per Quantity' ); // Title shown in admin
$this->method_description = __( 'Shipping Price per Quantity Method' ); // Description shown in admin
$this->title = "Per Quantity"; // This can be added as an setting but for this example its forced.
$this->init();
}
/**
* Init your settings
*
* @access public
* @return void
*/
function init() {
// Load the settings API
$this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings
$this->init_settings(); // This is part of the settings API. Loads settings you previously init.
$this->enabled = $this->get_option( 'enabled' );
$this->shipping_costs = $this->get_option( 'shipping_costs' );
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* Initialise Gateway Settings Form Fields
*/
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable Custom Cider Shipping', 'woocommerce' ),
'default' => 'no'
),
'shipping_costs' => array(
'title' => __( 'Define Shipping Costs', 'woocommerce' ),
'type' => 'text',
'label' => __( 'Define Shipping Costs', 'woocommerce' ),
'description' => 'First number is quantity, second number is price. Add comma between different quantities.'
)
);
}
/**
* Get items in package
* @param array $package
* @return int
*/
public function get_package_item_qty( $package ) {
$total_quantity = 0;
foreach ( $package['contents'] as $item_id => $values ) {
if ( $values['quantity'] > 0 && $values['data']->needs_shipping() ) {
$total_quantity += $values['quantity'];
}
}
return $total_quantity;
}
/**
* calculate_shipping function.
*
* @access public
* @param mixed $package
* @return void
*/
public function calculate_shipping( $package ) {
$rate = array(
'id' => $this->id,
'label' => $this->title,
'taxes' => ''
);
$quantity = $this->get_package_item_qty($package); // Get quantity
$array = array(); // Still suck at variable naming.
$newarray = array(); // Yet again
$array = explode(",",$this->shipping_costs); // shipping costs setting field, need to split
foreach ($array as $key => $value) {
$new = explode(" ",$value); // one more split to get quantity - price key/value
$newarray[$new[0]] = $new[1];
}
foreach ($newarray as $key => $value) {
if($quantity <= $key) {
$rate['cost'] = $value;
break;
}
}
// Register the rate
$this->add_rate( $rate );
}
}
}
}
add_action( 'woocommerce_shipping_init', 'cider_shipping_method_init' );
function add_cider_shipping_method( $methods ) {
$methods[] = 'Cider_Shipping_Method';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'add_cider_shipping_method' );
}
@ChamRun
Copy link

ChamRun commented Sep 5, 2023

Hey there! Take a look at line 93:

public function calculate_shipping( $package ) {

It should be changed as follows:

public function calculate_shipping( $package = array() ) {

@Irfanhaider05
Copy link

Irfanhaider05 commented Jul 2, 2024

public function calculate_shipping($package = array())
I use this function like this above but, $package is shown empty how I fix it ,
I need to get $package['destination']['address']; but in my case destination key is showing

tell u one thing this all in my custom plguin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment