Advertisement
borkolivic

Untitled

Mar 24th, 2016
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 22.13 KB | None | 0 0
  1. <?php
  2. /*
  3. Plugin Name: MX Woocommerce Local Pickup Extended
  4. Plugin URI: http://media-x.hr
  5. Description: Plugin for extending local pickup options
  6. Version: 1.0
  7. Author: Media X
  8. Author URI: http://media-x.hr
  9. License: GPLv3
  10. */
  11.  
  12. if (!class_exists('WC_Shipping_Options')) {
  13.    
  14.     function mx_shipping_methods_init() {
  15.    
  16.         class WC_Shipping_Options extends WC_Shipping_Method {
  17.            
  18.             public function __construct() {
  19.                 $this->id = 'mx_local_shipping';
  20.                 $this->method_title = __( 'Local Pickup Extended', 'wc_shipping_options' );
  21.                 $this->title = __('Local Pickup Extended');
  22.                 $this->options_array_label = 'mx_shipping_options';
  23.                 $this->method_description = __('Local shipping with user selectable options');
  24.                 add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
  25.                 add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_shipping_options' ) );
  26.                 $this->init();
  27.             }
  28.  
  29.             /**
  30.              * Init settings
  31.              *
  32.              * @access public
  33.              * @return void
  34.              */
  35.             function init() {
  36.                 // Load the settings API
  37.                 $this->init_form_fields();
  38.                 $this->init_settings();
  39.                
  40.                 // Define user set variables
  41.         $this->title        = $this->get_option( 'title' );
  42.         $this->type         = $this->get_option( 'type' );
  43.         $this->fee          = $this->get_option( 'fee' );
  44.         $this->type         = $this->get_option( 'type' );
  45.         $this->codes        = $this->get_option( 'codes' );
  46.         $this->availability = $this->get_option( 'availability' );
  47.         $this->countries    = $this->get_option( 'countries' );
  48.  
  49.                 $this->get_shipping_options();
  50.                
  51.                 add_filter( 'woocommerce_shipping_methods', array(&$this, 'add_mx_shipping_methods'));
  52.                 add_action('woocommerce_cart_totals_after_shipping', array(&$this, 'mx_review_order_shipping_options'));
  53.                 add_action('woocommerce_review_order_after_shipping', array(&$this, 'mx_review_order_shipping_options'));
  54.                 add_action( 'woocommerce_checkout_update_order_meta', array(&$this, 'mx_field_update_shipping_order_meta'), 10, 2);
  55.                 if (is_admin()) {
  56.                     add_action( 'woocommerce_admin_order_data_after_shipping_address', array(&$this, 'mx_display_shipping_admin_order_meta'), 10, 2 );
  57.                 }
  58.             }
  59.            
  60.             /**
  61.             * calculate_shipping function.
  62.             *
  63.             * @access public
  64.             * @param array $package (default: array())
  65.             * @return void
  66.             */
  67.            function calculate_shipping($package = array()) {
  68.                 $shipping_total = 0;
  69.                 $fee = ( trim($this->fee) == '' ) ? 0 : $this->fee;
  70.  
  71.                 if ($this->type == 'fixed')
  72.                     $shipping_total = $this->fee;
  73.  
  74.                 if ($this->type == 'percent')
  75.                     $shipping_total = $package['contents_cost'] * ( $this->fee / 100 );
  76.  
  77.                 if ($this->type == 'product') {
  78.                     foreach ($package['contents'] as $item_id => $values) {
  79.                         $_product = $values['data'];
  80.  
  81.                         if ($values['quantity'] > 0 && $_product->needs_shipping()) {
  82.                             $shipping_total += $this->fee * $values['quantity'];
  83.                         }
  84.                     }
  85.                 }
  86.  
  87.                 $rate = array(
  88.                     'id' => $this->id,
  89.                     'label' => $this->title,
  90.                     'cost' => $shipping_total
  91.                 );
  92.  
  93.                 $this->add_rate($rate);
  94.             }
  95.  
  96.             /**
  97.              * init_form_fields function.
  98.              *
  99.              * @access public
  100.              * @return void
  101.              */
  102.             function init_form_fields() {
  103.                 $this->form_fields = array(
  104.                     'enabled' => array(
  105.                         'title' => __('Enable', 'woocommerce'),
  106.                         'type' => 'checkbox',
  107.                         'label' => __('Enable Local Pickup Extended ', 'wc_shipping_options'),
  108.                         'default' => 'no'
  109.                     ),
  110.                     'title' => array(
  111.                         'title' => __('Title', 'woocommerce'),
  112.                         'type' => 'text',
  113.                         'description' => __('This controls the title which the user sees during checkout.', 'woocommerce'),
  114.                         'default' => __('Local Pickup With Options', 'wc_shipping_options'),
  115.                         'desc_tip' => true,
  116.                     ),
  117.                     'type' => array(
  118.                         'title' => __('Fee Type', 'woocommerce'),
  119.                         'type' => 'select',
  120.                         'description' => __('How to calculate delivery charges', 'woocommerce'),
  121.                         'default' => 'fixed',
  122.                         'options' => array(
  123.                             'fixed' => __('Fixed amount', 'woocommerce'),
  124.                             'percent' => __('Percentage of cart total', 'woocommerce'),
  125.                             'product' => __('Fixed amount per product', 'woocommerce'),
  126.                         ),
  127.                         'desc_tip' => true,
  128.                     ),
  129.                     'fee' => array(
  130.                         'title' => __('Delivery Fee', 'woocommerce'),
  131.                         'type' => 'price',
  132.                         'description' => __('What fee do you want to charge for local delivery, disregarded if you choose free. Leave blank to disable.', 'woocommerce'),
  133.                         'default' => '',
  134.                         'desc_tip' => true,
  135.                         'placeholder' => wc_format_localized_price(0)
  136.                     ),
  137.                     'shipping_options_table' => array(
  138.                         'type' => 'shipping_options_table'
  139.                     ),
  140.                     'codes' => array(
  141.                         'title' => __('Zip/Post Codes', 'woocommerce'),
  142.                         'type' => 'textarea',
  143.                         'description' => __('What zip/post codes can use the local pickup option? Separate codes with a comma. Accepts wildcards, e.g. P* will match a postcode of PE30.', 'woocommerce'),
  144.                         'default' => '',
  145.                         'desc_tip' => true,
  146.                         'placeholder' => '12345 etc'
  147.                     ),
  148.                     'availability' => array(
  149.                         'title' => __('Method availability', 'woocommerce'),
  150.                         'type' => 'select',
  151.                         'default' => 'all',
  152.                         'class' => 'availability',
  153.                         'options' => array(
  154.                             'all' => __('All allowed countries', 'woocommerce'),
  155.                             'specific' => __('Specific Countries', 'woocommerce')
  156.                         )
  157.                     ),
  158.                     'countries' => array(
  159.                         'title' => __('Specific Countries', 'woocommerce'),
  160.                         'type' => 'multiselect',
  161.                         'class' => 'chosen_select',
  162.                         'css' => 'width: 450px;',
  163.                         'default' => '',
  164.                         'options' => WC()->countries->get_shipping_countries(),
  165.                         'custom_attributes' => array(
  166.                             'data-placeholder' => __('Select some countries', 'woocommerce')
  167.                         )
  168.                     )
  169.                 );
  170.             }
  171.            
  172.             /**
  173.             * admin_options function.
  174.             *
  175.             * @access public
  176.             * @return void
  177.             */
  178.            function admin_options() {
  179.                    ?>
  180.                    <h3><?php echo $this->method_title; ?></h3>
  181.                    <p><?php _e( 'Local pickup is a simple shipping method for picking up orders locally, on multiple locations.', 'woocommerce' ); ?></p>
  182.                    <table class="form-table">
  183.                            <?php $this->generate_settings_html(); ?>
  184.                    </table> <?php
  185.            }
  186.            
  187.            /**
  188.              * is_available function.
  189.              *
  190.              * @access public
  191.              * @param array $package
  192.              * @return bool
  193.              */
  194.             function is_available($package) {
  195.  
  196.                 if ($this->enabled == "no")
  197.                     return false;
  198.  
  199.                 // If post codes are listed, let's use them.
  200.                 $codes = '';
  201.                 if ($this->codes != '') {
  202.                     foreach (explode(',', $this->codes) as $code) {
  203.                         $codes[] = $this->clean($code);
  204.                     }
  205.                 }
  206.  
  207.                 if (is_array($codes)) {
  208.  
  209.                     $found_match = false;
  210.  
  211.                     if (in_array($this->clean($package['destination']['postcode']), $codes)) {
  212.                         $found_match = true;
  213.                     }
  214.  
  215.  
  216.                     // Pattern match
  217.                     if (!$found_match) {
  218.  
  219.                         $customer_postcode = $this->clean($package['destination']['postcode']);
  220.                         foreach ($codes as $c) {
  221.                             $pattern = '/^' . str_replace('_', '[0-9a-zA-Z]', $c) . '$/i';
  222.                             if (preg_match($pattern, $customer_postcode)) {
  223.                                 $found_match = true;
  224.                                 break;
  225.                             }
  226.                         }
  227.                     }
  228.  
  229.  
  230.                     // Wildcard search
  231.                     if (!$found_match) {
  232.  
  233.                         $customer_postcode = $this->clean($package['destination']['postcode']);
  234.                         $customer_postcode_length = strlen($customer_postcode);
  235.  
  236.                         for ($i = 0; $i <= $customer_postcode_length; $i++) {
  237.  
  238.                             if (in_array($customer_postcode, $codes)) {
  239.                                 $found_match = true;
  240.                             }
  241.  
  242.                             $customer_postcode = substr($customer_postcode, 0, -2) . '*';
  243.                         }
  244.                     }
  245.  
  246.                     if (!$found_match) {
  247.                         return false;
  248.                     }
  249.                 }
  250.  
  251.                 // Either post codes not setup, or post codes are in array... so lefts check countries for backwards compatibility.
  252.                 if ($this->availability == 'specific') {
  253.                     $ship_to_countries = $this->countries;
  254.                 } else {
  255.                     $ship_to_countries = array_keys(WC()->countries->get_shipping_countries());
  256.                 }
  257.  
  258.                 if (is_array($ship_to_countries)) {
  259.                     if (!in_array($package['destination']['country'], $ship_to_countries)) {
  260.                         return false;
  261.                     }
  262.                 }
  263.  
  264.                 // Yay! We passed!
  265.                 return apply_filters('woocommerce_shipping_' . $this->id . '_is_available', true, $package);
  266.             }
  267.  
  268.             /**
  269.              * clean function.
  270.              *
  271.              * @access public
  272.              * @param mixed $code
  273.              * @return string
  274.              */
  275.             function clean($code) {
  276.                 return str_replace('-', '', sanitize_title($code)) . ( strstr($code, '*') ? '*' : '' );
  277.             }
  278.            
  279.             /**
  280.             * validate_shipping_options_table_field function.
  281.             *
  282.             * @access public
  283.             * @param mixed $key
  284.             * @return bool
  285.             */
  286.             function validate_shipping_options_table_field( $key ) {
  287.                 return false;
  288.             }
  289.            
  290.             /**
  291.              * generate_options_table_html function.
  292.              *
  293.              * @access public
  294.              * @return string
  295.              */
  296.             function generate_shipping_options_table_html() {
  297.                 ob_start();
  298.                 ?>
  299.                     <tr valign="top">
  300.                         <th scope="row" class="titledesc"><?php _e('Pickup Options', 'woocommerce'); ?>:</th>
  301.                         <td class="forminp" id="<?php echo $this->id; ?>_options">
  302.                         <table class="shippingrows widefat" cellspacing="0">
  303.                             <thead>
  304.                                 <tr>
  305.                                     <th class="check-column"><input type="checkbox"></th>
  306.                                     <th class="options-th"><?php _e('Option', 'woocommerce'); ?></th>
  307.                                 </tr>
  308.                             </thead>
  309.                             <tbody>
  310.                             <?php
  311.                                 $i = -1;
  312.                                 if ($this->shipping_options) :
  313.                                     foreach ($this->shipping_options as $option) :
  314.                                         $i++;
  315.                             ?>
  316.                                         <tr class="option-tr">
  317.                                             <th class="check-column"><input type="checkbox" name="select" /></th>
  318.                                             <td><input type="text" name="<?php echo esc_attr($this->id . '_options[' . $i . ']') ?>" value="<?php echo $option; ?>"></td>
  319.                                         </tr>
  320.                             <?php endforeach; endif; ?>
  321.                             </tbody>
  322.                             <tfoot>
  323.                                 <tr>
  324.                                     <th colspan="4"><a href="#" class="add button"><?php _e('Add Option', 'woocommerce'); ?></a> <a href="#" class="remove button"><?php _e('Delete selected options', 'woocommerce'); ?></a></th>
  325.                                 </tr>
  326.                             </tfoot>
  327.                         </table>
  328.                         <script type="text/javascript">
  329.                             jQuery(function() {
  330.  
  331.                                 jQuery('#<?php echo $this->id; ?>_options').on( 'click', 'a.add', function(){
  332.                                     var size = jQuery('#<?php echo $this->id; ?>_options tbody .option-tr').size();
  333.                                     jQuery('<tr class="option-tr"><th class="check-column"><input type="checkbox" name="select" /></th>' +
  334.                                            '<td><input type="text" name="<?php echo esc_attr($this->id . '_options') ?>[' + size + ']" /></td></tr>')
  335.                                         .appendTo('#<?php echo $this->id; ?>_options table tbody');
  336.                                     return false;
  337.                                 });
  338.  
  339.                                 // Remove row
  340.                                 jQuery('#<?php echo $this->id; ?>_options').on( 'click', 'a.remove', function(){
  341.                                     var answer = confirm("<?php _e('Delete the selected options?', 'woocommerce'); ?>");
  342.                                     if (answer) {
  343.                                         jQuery('#<?php echo $this->id; ?>_options table tbody tr th.check-column input:checked').each(function(i, el){
  344.                                                 jQuery(el).closest('tr').remove();
  345.                                         });
  346.                                     }
  347.                                     return false;
  348.                                 });
  349.  
  350.                             });
  351.                         </script>
  352.                         </td>
  353.                     </tr>
  354.                 <?php
  355.                 return ob_get_clean();
  356.             }
  357.            
  358.             /**
  359.              * process_shipping_options function.
  360.              *
  361.              * @access public
  362.              * @return void
  363.              */
  364.             function process_shipping_options() {
  365.                
  366.                 $options = array();
  367.  
  368.                 if (isset($_POST[$this->id . '_options']))
  369.                     $options = array_map('wc_clean', $_POST[$this->id . '_options']);
  370.  
  371.                 update_option($this->options_array_label, $options);
  372.                
  373.                 $this->get_shipping_options();
  374.             }
  375.  
  376.             /**
  377.             * get_shipping_options function.
  378.             *
  379.             * @access public
  380.             * @return void
  381.             */
  382.            function get_shipping_options() {
  383.                    $this->shipping_options = array_filter( (array) get_option( $this->options_array_label ) );
  384.            }
  385.            
  386.            function mx_review_order_shipping_options() {
  387.                 global $woocommerce;
  388.                 $chosen_method = $woocommerce->session->get('chosen_shipping_methods');
  389.                 if (is_array($chosen_method) && in_array($this->id, $chosen_method)) {
  390.                     echo '<tr class="shipping_option">';
  391.                     echo '<th> '.__('Choose store', 'woocommerce').': </th>';
  392.                     echo '<td><select name="shipping_option" class="input-select" id="shipping_option" style="max-width:200px;" required="required">';
  393.                     echo '<option value=""> '.__('Select Location', 'woocommerce').' </option>';
  394.                     foreach ($this->shipping_options as $option) {
  395.                         echo '<option value="' . esc_attr($option) . '" ' . selected( $woocommerce->session->_chosen_shipping_option, esc_attr($option) ) . '>' . $option . '</option>';
  396.                     }
  397.                     echo '</select></td></tr>';
  398.                    
  399.                     ?>
  400.                         <script>
  401.                             var options = document.getElementsByName("shipping_option");
  402.                             if (options.length >= 1) {
  403.                                 options[0].addEventListener("change", function() {
  404.                                     var data = "action=mx_save_selected&shipping_option=" + this.value;
  405.                                     var xmlhttp;
  406.                                     if (window.XMLHttpRequest) {
  407.                                         xmlhttp = new XMLHttpRequest();
  408.                                     } else {
  409.                                         xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  410.                                     }
  411.                                     xmlhttp.open('GET', '<?php echo admin_url( 'admin-ajax.php' ); ?>?' + data, true);
  412.                                     xmlhttp.send();
  413.                                 });
  414.                             }
  415.                         </script>
  416.                     <?php
  417.                 }
  418.             }
  419.            
  420.             function mx_field_update_shipping_order_meta( $order_id, $posted ) {
  421.                 global $woocommerce;
  422.                 if (is_array($posted['shipping_method']) && in_array($this->id, $posted['shipping_method'])) {
  423.                     if ( isset( $_POST['shipping_option'] ) && !empty( $_POST['shipping_option'] ) ) {
  424.                         update_post_meta( $order_id, 'mx_shipping_option', sanitize_text_field( $_POST['shipping_option'] ) );
  425.                         $woocommerce->session->_chosen_shipping_option = sanitize_text_field( $_POST['shipping_option'] );
  426.                     }
  427.                 } else { //visible  in cart, hidden in checkout
  428.                     $chosen_method = $woocommerce->session->get('chosen_shipping_methods');
  429.                     $chosen_option= $woocommerce->session->_chosen_shipping_option;
  430.                     if (is_array($chosen_method) && in_array($this->id, $chosen_method) && $chosen_option) {
  431.                         update_post_meta( $order_id, 'mx_shipping_option', $woocommerce->session->_chosen_shipping_option );
  432.                     }
  433.                 }
  434.             }
  435.          
  436.             function mx_display_shipping_admin_order_meta($order){
  437.                 $selected_option = get_post_meta( $order->id, 'mx_shipping_option', true );
  438.                 if ($selected_option) {
  439.                     echo '<p><strong>' . $this->title . ':</strong> ' . get_post_meta( $order->id, 'mx_shipping_option', true ) . '</p>';
  440.                 }
  441.             }
  442.            
  443.             function add_mx_shipping_methods( $methods ) {
  444.                 $methods[] = $this;
  445.                 return $methods;
  446.             }
  447.            
  448.         }
  449.        
  450.         new WC_Shipping_Options();
  451.  
  452.     }
  453.            add_action( 'woocommerce_order_details_after_order_table', 'mx_shipping_display_custom_order_meta', 10, 1 );
  454.  
  455.            function mx_shipping_display_custom_order_meta($order){
  456.               $selected_option = get_post_meta( $order->id, 'mx_shipping_option', true );
  457.               if ($selected_option) {
  458.                   echo '<p><strong>'.__('Pickup Location', 'woocommerce').':</strong> ' . get_post_meta( $order->id, 'mx_shipping_option', true ). '</p>';
  459.               }
  460.            }
  461.           /**
  462.          
  463.           * add our shipping meta to order emails
  464.  
  465.            */
  466.            add_filter('woocommerce_email_order_meta_keys', 'mx_shipping_option_meta_keys');
  467.  
  468.              function mx_shipping_option_meta_keys( $keys ) {
  469.                 if ( isset( $_POST['shipping_option'] ) && !empty( $_POST['shipping_option'] ) ) {
  470.                 echo '<h2>'.__('Pickup Location', 'woocommerce').':</h2>';
  471.      
  472.                 $keys[''] = 'mx_shipping_option';
  473.                 return $keys;
  474.                 }
  475.             }
  476.    
  477.            add_action('woocommerce_shipping_init', 'mx_shipping_methods_init');
  478.  
  479.    
  480.          add_action( 'wp_ajax_mx_save_selected', 'mx_save_selected' );  
  481.          add_action( 'wp_ajax_nopriv_mx_save_selected', 'mx_save_selected' );
  482.            function mx_save_selected() {
  483.                  if ( isset( $_GET['shipping_option'] ) && !empty( $_GET['shipping_option'] ) ) {
  484.             global $woocommerce;
  485.             $selected_option = $_GET['shipping_option'];
  486.             $woocommerce->session->_chosen_shipping_option = sanitize_text_field( $selected_option );
  487.         }
  488.         die();
  489.     }
  490. }
  491.  
  492. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement