Skip to content

Instantly share code, notes, and snippets.

@atwellpub
Created November 1, 2018 02:27
Show Gist options
  • Save atwellpub/e013246a97fd4f3bcb8199813eabb86a to your computer and use it in GitHub Desktop.
Save atwellpub/e013246a97fd4f3bcb8199813eabb86a to your computer and use it in GitHub Desktop.
<?php
/**
* @credits https://jeroensormani.com/adding-a-custom-woocommerce-product-type/
*/
//error_reporting(E_ALL);
//ini_set('display_errors', 1);
add_action('init' , 'wc_pm_load_product_type');
function wc_pm_load_product_type() {
class WC_Product_Price_Matrix extends WC_Product_Variation {
public function __construct( $product) {
$this->product_type = 'price_matrix';
parent::__construct( $product );
}
/**
* Get internal type.
* Needed for WooCommerce 3.0 Compatibility
* @return string
*/
public function get_type() {
return 'price_matrix';
}
public static function load_hooks() {
/* adds price matrix to selectable product type dropdown */
add_filter( 'product_type_selector', array( __CLASS__ , 'add_product_type_to_dropdown' ) );
/* manages available tabs for price matrix product */
add_filter( 'woocommerce_product_data_tabs', array( __CLASS__ , 'manage_tabs') );
/* show price matrix select tab */
add_action( 'woocommerce_product_data_panels', array( __CLASS__ , 'display_price_matrix_select') );
/* save handler for product meta */
add_action( 'woocommerce_process_product_meta', array(__CLASS__ , 'save_matrix_selection') );
/* make sure our matrix based products are labeled as purchasable if they have a stock */
add_filter( 'woocommerce_is_purchasable', array( __CLASS__ , 'set_matrix_purchasable' ), 1000, 2);
add_filter( 'woocommerce_variation_is_purchasable', array( __CLASS__ , 'set_matrix_purchasable' ), 1000, 2);
/* loads our add to cart template for price matrix product types */
add_action( 'woocommerce_price_matrix_add_to_cart', array( __CLASS__ , 'price_matrix_add_to_cart') );
/* set price defaults when product type is price_matrix */
add_filter( 'woocommerce_get_variation_prices_price', array( __CLASS__ ,'set_default_variation_price'), 10, 3 );
add_filter( 'woocommerce_get_variation_prices_regular_price', array( __CLASS__ ,'set_default_variation_price'), 10, 3 );
add_filter( 'woocommerce_get_variation_prices_sale_price', array( __CLASS__ ,'set_default_variation_price'), 10, 3 );
/* delete all json files durring setting update. */
add_action('acf/save_post', array( __CLASS__ , 'delete_json_files' ), 20);
/* todo understand better */
/* apply patch that prevents urlencode errors for price_matrix product type */
add_filter('woocommerce_product_variation_get_attributes' , array( __CLASS__ , 'correct_attributes' ) , 10 , 2);
}
/**
* manages available tabs for price matrix product
*/
public static function add_product_type_to_dropdown( $types ){
$types[ 'price_matrix' ] = __( 'Use Price Matrix' , 'woocommerce-price-matrices' );
return $types;
}
/**
* Add a custom product tab.
*/
public static function manage_tabs( $tabs) {
/* add price matrix tab */
$tabs['price_matrix'] = array(
'label' => __( 'Select Matrix', 'woocommerce' ),
'target' => 'price_matrix',
'class' => array( 'show_if_price_matrix', 'hide_if_virtual','hide_if_grouped','hide_if_external' ),
);
/* control tabs */
$tabs['inventory']['class'][] = 'show_if_price_matrix';
$tabs['variations']['class'][] = 'show_if_price_matrix';
$tabs['attribute']['class'][] = 'show_if_price_matrix';
$tabs['attribute']['class'][] = 'show_if_variable';
$tabs['attribute']['class'][] = 'show_if_simple';
return $tabs;
}
/**
* Contents of the rental options product tab.
*/
function display_price_matrix_select() {
global $post, $product;
$matrices = WC_PM_Edit_Prices::get_matrices()
?>
<div id='price_matrix' class='panel woocommerce_options_panel'>
<div class='options_group'>
<?php
woocommerce_wp_select( array(
'label' => __( 'Select Matrix ', 'woocommerce-price-matrices' ),
'id' => 'selected_matrix',
'class' => '',
'style' => '',
'wrapper_class' => '',
'options' => WC_PM_Edit_Prices::get_matrices(true),
'desc_tip' => '',
'description' => __( 'Select which matrix rules to apply to this product\'s pricing rule', 'woocommerce-price-matrices' ),
));
woocommerce_wp_text_input( array(
'label' => __( 'X Input Min', 'woocommerce-price-matrices' ),
'id' => 'matrix_x_min',
'class' => '',
'style' => '',
'wrapper_class' => '',
'desc_tip' => '',
'description' => __( 'When inputs are user definable, set the min number input for the x axis.', 'woocommerce-price-matrices' ),
));
woocommerce_wp_text_input( array(
'label' => __( 'X Input Max', 'woocommerce-price-matrices' ),
'id' => 'matrix_x_max',
'class' => '',
'style' => '',
'wrapper_class' => '',
'desc_tip' => '',
'description' => __( 'When inputs are user definable, set the max number input for the x axis.', 'woocommerce-price-matrices' ),
));
woocommerce_wp_text_input( array(
'label' => __( 'Y Input Min', 'woocommerce-price-matrices' ),
'id' => 'matrix_y_min',
'class' => '',
'style' => '',
'wrapper_class' => '',
'desc_tip' => '',
'description' => __( 'When inputs are user definable, set the min number input for the y axis.', 'woocommerce-price-matrices' ),
));
woocommerce_wp_text_input( array(
'label' => __( 'Y Input Max', 'woocommerce-price-matrices' ),
'id' => 'matrix_y_max',
'class' => '',
'style' => '',
'wrapper_class' => '',
'desc_tip' => '',
'description' => __( 'When inputs are user definable, set the max number input for the y axis.', 'woocommerce-price-matrices' ),
));
?>
</div>
</div>
<?php
$_product = wc_get_product( $post->ID );
if( $_product->is_type( 'price_matrix' ) ) {
?>
<style>
.show_if_variable {
display: block !important;
}
</style>
<?php
}
}
/**
* Saves matrix selection data
* @param $post_id
*/
public static function save_matrix_selection( $post_id ) {
if (!isset($_POST['selected_matrix']) || $_POST['selected_matrix'] == 'null') {
return;
}
/* save matrix selection */
$selcted_matrix = (int) $_POST['selected_matrix'];
$product = wc_get_product( $post_id );
$product->update_meta_data( 'selected_matrix', $selcted_matrix );
$product->update_meta_data( 'matrix_x_min', (int) $_POST['matrix_x_min'] );
$product->update_meta_data( 'matrix_x_max', (int) $_POST['matrix_x_max'] );
$product->update_meta_data( 'matrix_y_min', (int) $_POST['matrix_y_min'] );
$product->update_meta_data( 'matrix_y_max', (int) $_POST['matrix_y_max'] );
$product->update_meta_data( '_visibility' , 'visible' );
/* clear related cache */
delete_transient('price-matrix-base-offer-' . $post_id);
$product->save();
}
/**
* Set matrix based products as purchasable if they have stock
* @param $is_purchasable
* @param $object
*/
public static function set_matrix_purchasable( $is_purchasable, $object ) {
$_product = wc_get_product( $object->id );
if( $is_purchasable || !$_product->is_type( 'price_matrix' ) ) {
return $is_purchasable;
}
if ( $_product->is_in_stock() ) {
return true;
} else {
return false;
}
}
/**
* Tells woocommerc which template to load for the add to cart feature
*/
public static function price_matrix_add_to_cart() {
global $product;
$variations = new WC_Product_Variable( $product->id );
$matrix_id = get_post_meta( $product->id , 'selected_matrix', true );
if ($matrix_id ==="") {
return;
}
$matrix = WC_PM_Edit_Prices::get_details_from_matrix_id( $matrix_id );
wc_get_template( 'single-product/add-to-cart/price_matrix.php' , array(
'variations' => $variations,
'available_variations' => $variations->get_available_variations(),
'attributes' => $variations->get_variation_attributes(),
'selected_attributes' => $variations->get_default_attributes(),
'matrix' => $matrix,
) );
}
/**
* sets the default price of variations
*/
public static function set_default_variation_price( $price , $variation, $product ) {
return $price;
}
/**
* Clears all matrix json files every time settings save
*/
public static function delete_json_files() {
$screen = get_current_screen();
if ($screen->id != 'woocommerce_page_acf-options-matrices') {
return;
}
if (!is_dir(WOOCOM_MATRICES_UPLOADS_PATH)) {
return;
}
$files = glob( WOOCOM_MATRICES_UPLOADS_PATH . '*', GLOB_MARK);
foreach ($files as $file) {
unlink($file);
}
}
/**
* Function replacement placeholder
*/
public function add_to_cart_url() {
global $product;
}
/**
* Convert object values to array inside product attributes
* @param $value
* @param $context
*/
public static function correct_attributes( $value , $context ) {
if (!is_array($value) || $context->product_type != 'price_matrix' ) {
return $value;
}
if ( is_page( 'cart' ) || is_cart() ) {
return array();
}
return $value;
}
}
/* load hooks */
WC_Product_Price_Matrix::load_hooks();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment