Last active
June 5, 2020 15:20
-
-
Save RadGH/b7b69f65bbeb7212083058d1d644b0c9 to your computer and use it in GitHub Desktop.
Modified version of "class-wc-boxpack.php" version "3.2.18". See: https://gist.github.com/RadGH/7c8f0ef77e242ce011932d41e9c06b8e
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* WooCommerce Box Packer | |
* | |
* @version 2.0.1 | |
* @author WooThemes / Mike Jolley | |
*/ | |
class WC_Boxpack { | |
private $boxes; | |
private $items; | |
private $packages; | |
private $cannot_pack; | |
/** | |
* __construct function. | |
* | |
* @access public | |
* @return void | |
*/ | |
public function __construct() { | |
include_once( 'class-wc-boxpack-box.php' ); | |
include_once( 'class-wc-boxpack-item.php' ); | |
} | |
/** | |
* clear_items function. | |
* | |
* @access public | |
* @return void | |
*/ | |
public function clear_items() { | |
$this->items = array(); | |
} | |
/** | |
* clear_boxes function. | |
* | |
* @access public | |
* @return void | |
*/ | |
public function clear_boxes() { | |
$this->boxes = array(); | |
} | |
/** | |
* add_item function. | |
* | |
* @access public | |
* @return void | |
*/ | |
public function add_item( $length, $width, $height, $weight, $value = '', $meta = array() ) { | |
$this->items[] = new WC_Boxpack_Item( $length, $width, $height, $weight, $value, $meta ); | |
} | |
/** | |
* add_box function. | |
* | |
* @access public | |
* @param mixed $length | |
* @param mixed $width | |
* @param mixed $height | |
* @param mixed $weight | |
* @return void | |
*/ | |
public function add_box( $length, $width, $height, $weight = 0 ) { | |
$new_box = new WC_Boxpack_Box( $length, $width, $height, $weight ); | |
$this->boxes[] = $new_box; | |
return $new_box; | |
} | |
/** | |
* add_package function. | |
* | |
* @access public | |
* @param mixed $length | |
* @param mixed $width | |
* @param mixed $height | |
* @param mixed $weight | |
* @param mixed $value | |
* @return void | |
*/ | |
public function add_package( $length, $width, $height, $weight = 0, $value = 0 ) { | |
$package = new stdClass(); | |
$package->id = ''; | |
$package->weight = $length; | |
$package->length = $width; | |
$package->width = $height; | |
$package->height = $weight; | |
$package->value = $value; | |
$package->unpacked = true; | |
$this->packages[] = $package; | |
} | |
/** | |
* get_packages function. | |
* | |
* @access public | |
* @return void | |
*/ | |
public function get_packages() { | |
return $this->packages ? $this->packages : array(); | |
} | |
/** | |
* pack function. | |
* | |
* @access public | |
* @return void | |
*/ | |
public function pack() { | |
try { | |
// We need items | |
if ( sizeof( $this->items ) == 0 ) { | |
throw new Exception( 'No items to pack!' ); | |
} | |
// Clear packages | |
$this->packages = array(); | |
// Order the boxes by volume | |
$this->boxes = $this->order_boxes( $this->boxes ); | |
if ( ! $this->boxes ) { | |
$this->cannot_pack = $this->items; | |
$this->items = array(); | |
} | |
// Keep looping until packed | |
while ( sizeof( $this->items ) > 0 ) { | |
$this->items = $this->order_items( $this->items ); | |
$possible_packages = array(); | |
$best_package = ''; | |
// Attempt to pack all items in each box | |
foreach ( $this->boxes as $box ) { | |
$possible_packages[] = $box->pack( $this->items ); | |
} | |
// Find the best success rate | |
$best_percent = 0; | |
foreach ( $possible_packages as $package ) { | |
if ( $package->percent > $best_percent ) { | |
$best_percent = $package->percent; | |
} | |
} | |
if ( $best_percent == 0 ) { | |
$this->cannot_pack = $this->items; | |
$this->items = array(); | |
} else { | |
// Get smallest box with best_percent | |
$possible_packages = array_reverse( $possible_packages ); | |
foreach ( $possible_packages as $package ) { | |
if ( $package->percent == $best_percent ) { | |
$best_package = $package; | |
break; // Done packing | |
} | |
} | |
// Update items array | |
$this->items = $best_package->unpacked; | |
// Store package | |
$this->packages[] = $best_package; | |
} | |
} | |
// Items we cannot pack (by now) get packaged individually | |
if ( $this->cannot_pack ) { | |
foreach ( $this->cannot_pack as $item ) { | |
$package = new stdClass(); | |
$package->id = ''; | |
$package->weight = $item->get_weight(); | |
$package->length = $item->get_length(); | |
$package->width = $item->get_width(); | |
$package->height = $item->get_height(); | |
$package->value = $item->get_value(); | |
$package->unpacked = true; | |
$this->packages[] = $package; | |
} | |
} | |
} catch ( Exception $e ) { | |
// Display a packing error for admins | |
if ( current_user_can( 'manage_options' ) ) { | |
echo 'Packing error: ', $e->getMessage(), "\n"; | |
} | |
} | |
} | |
/** | |
* Order boxes by weight and volume | |
* $param array $sort | |
* @return array | |
*/ | |
private function order_boxes( $sort ) { | |
if ( ! empty( $sort ) ) { | |
uasort( $sort, array( $this, 'box_sorting' ) ); | |
} | |
return $sort; | |
} | |
/** | |
* Order items by weight and volume | |
* $param array $sort | |
* @return array | |
*/ | |
private function order_items( $sort ) { | |
if ( ! empty( $sort ) ) { | |
uasort( $sort, array( $this, 'item_sorting' ) ); | |
} | |
return $sort; | |
} | |
/** | |
* order_by_volume function. | |
* | |
* @access private | |
* @return void | |
*/ | |
private function order_by_volume( $sort ) { | |
if ( ! empty( $sort ) ) { | |
uasort( $sort, array( $this, 'volume_based_sorting' ) ); | |
} | |
return $sort; | |
} | |
/** | |
* item_sorting function. | |
* | |
* @access public | |
* @param mixed $a | |
* @param mixed $b | |
* @return void | |
*/ | |
public function item_sorting( $a, $b ) { | |
if ( $a->get_volume() == $b->get_volume() ) { | |
if ( $a->get_weight() == $b->get_weight() ) { | |
return 0; | |
} | |
return ( $a->get_weight() < $b->get_weight() ) ? 1 : -1; | |
} | |
return ( $a->get_volume() < $b->get_volume() ) ? 1 : -1; | |
} | |
/** | |
* box_sorting function. | |
* | |
* @access public | |
* @param mixed $a | |
* @param mixed $b | |
* @return void | |
*/ | |
public function box_sorting( $a, $b ) { | |
if ( $a->get_volume() == $b->get_volume() ) { | |
if ( $a->get_max_weight() == $b->get_max_weight() ) { | |
return 0; | |
} | |
return ( $a->get_max_weight() < $b->get_max_weight() ) ? 1 : -1; | |
} | |
return ( $a->get_volume() < $b->get_volume() ) ? 1 : -1; | |
} | |
/** | |
* volume_based_sorting function. | |
* | |
* @access public | |
* @param mixed $a | |
* @param mixed $b | |
* @return void | |
*/ | |
public function volume_based_sorting( $a, $b ) { | |
if ( $a->get_volume() == $b->get_volume() ) { | |
return 0; | |
} | |
return ( $a->get_volume() < $b->get_volume() ) ? 1 : -1; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment