0

This is a plugin for a specific shipping method for woocommerce.

I'm trying to add a form into a new shipment method for WooCommerce I create. In that form I wan the user to enter street and postal code and then press Ok-button. The click should pick up value from street and postal_code and then return a delivery location from DHL based on those values.

It's no problem to execute the click event when clicking on the button (in javascript), but the javascript then runs an ajax-call that do fail and returns 400 bad gateway.

I know that the reason is that the rows:

 add_action( 'wp_ajax_checklocation', array ( $this, 'location') );
 add_action( 'wp_ajax_nopriv_checklocation', array ( $this, 'location') );  

does not get registered for some reason, but I don't know why? Is the code located in wrong location of code? Or something else that I am missing? The location function is simply never called even if my ajax-call in my javascript looks like this:

var check_dhl_location = $.ajax({            
            type: 'POST',
            data:{
                action: 'checklocation',    
                dhlsweden_shipping_adr: shipping_adr,
                dhlsweden_shipping_postalcode: shipping_postalcode 
            },
            url: MyAjax.ajaxurl,
            dataType: 'json'
        });

Please help me with a clue or even better a solution :-) Down below is nearly all code:

<?php
defined( 'ABSPATH' ) or die( 'No access allowed!' );

//Check if WooCommerce is active
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
    function dhlsweden_shipping_method_init() {
            if ( ! class_exists( 'WC_Shipping_DHLsweden' ) ) {
                    class WC_Shipping_DHLsweden extends WC_Shipping_Method {

                            const client_key = 'I wont tell here!!!'; //Client-key is genereated in DHL Dashboard 

                            const base_url = 'https://api.freight-logistics.dhl.com/';
                            const homedelivery_url = 'homedeliverylocatorapi/v1/';
                            const ping = 'homedeliverylocator/ping';

                            const servicepointlocator_url = 'servicepointlocatorapi/';
                            const nearest_servicepoints = 'servicepoint/findnearestservicepoints';

                            /**
                             * Constructor for your shipping class
                             *
                             * @access public
                             * @return void
                             */
                            public function __construct( $instance_id = 0 ) 
                            {          
                                //Initate ajax-functionality both admin and frontend
                                add_action( 'wp_ajax_checklocation', array ( $this, 'location') );
                                add_action( 'wp_ajax_nopriv_checklocation', array ( $this, 'location') );  

                                $this->load_js();



                            }



                            /* THIS function is NOT called */
                            public function location() {
                                $location = array();
                                /*
                                 * $shipping_adr =  filter_input( INPUT_POST, 'dhlsweden_shipping_adr' );
                                $postal_code = filter_input( INPUT_POST , 'dhlsweden_shipping_postalcode' );
                                */


                                error_log($shipping_adr, 3, 'dhlsweden.log');
                                error_log($postal_code, 3, 'dhlsweden.log');
                                error_log(print_r($location,true), 3, 'dhlsweden.log');


                                echo json_encode($location);
                                wp_die();
                            }



                            public function api_getlocations() { 
                                $fieldset = WC()->checkout()->checkout_fields;   
                                //var_dump($fieldset);
                                $shipping_adr = WC()->checkout()->get_value('shipping_address_1');
                                $postal_code = WC()->checkout()->get_value('shipping_postcode');

                                //Default values
                                if (!isset($shipping_adr) || !isset($postal_code)) 
                                {
                                    //Form with ajax functionality
                                    $form = '<form id="frmGetLocations" action="" name="">';
                                    $form .= '<input type="text" id="dhlsweden_shipping_adr" name="dhlsweden_shipping_adr" placeholder="Ange gatuadress">';
                                    $form .= '<input type="text" id="dhlsweden_shipping_postalcode" name="dhlsweden_shipping_postalcode" placeholder="Ange postnr">';
                                    $form .= '<input type="button" id="dhlsweden_button_shippinglocations" name="dhlsweden_button_shippinglocations" value="Ok">';
                                    $form .= '</form>';


                                    $form .= '<select id="dhlsweden_delivery" name="delivery">';
                                    $form .= '</select>';

                                    return array('userform' => $form);   //This function returns array only                                  
                                }
                                $adr_arr = explode(' ', $shipping_adr);
                                $street = $adr_arr[0];
                                $street_number = $adr_arr[1];


                                //var_dump($fn2);                                


                                $api_url = self::base_url . self::servicepointlocator_url . self::nearest_servicepoints;       
                                $addr['address'] = array(
                                            'street' => $street,
                                            'streetNumber' => $street_number,
                                            'additionalAddressInfo' => '',
                                            'cityName' => '', 
                                            'postalCode' => $postal_code,
                                            'countryCode' => ''
                                );
                                $feature_codes = array('featureCodes' => array(''));
                                $bit_cat_codes = array('bitCatCodes' => array(''));
                                $max_nr_items = array('maxNumberOfItems' => 0);

                                $json_data = array_merge($addr, $feature_codes,$bit_cat_codes,$max_nr_items);
                                $jd = json_encode($json_data);       
                                /*
                                 * var_dump($jd);
                                 */

                                //Response from DHL server
                                $dhl_response = wp_remote_post(
                                    $api_url ,
                                    array(
                                        'headers' => array( 'client-key' => self::client_key, 'accept' => 'text/plain', 'Content-Type' => 'application/json-patch+json' ),
                                        'body' => $jd
                                        ) //Client-key is genereated in DHL Dashboard 
                                    ); 
                                $json_arr = json_decode($dhl_response['body'],true);

                                $service_points = array();
                                foreach($json_arr['servicePoints'] as $sp) {
                                    $service_points[] = array('id' => $sp['id'],
                                                              'name' => $sp['name']);                                           
                                }                                
                                return $service_points;


                            }


                            /**
                             * 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.
                                    // Save settings in admin if you have any defined

                                    $this->supports = array(
                                                                'settings',
                                                                'shipping-zones',
                                                                'instance-settings',
                                                                'instance-settings-modal'                                            
                                                            );

                                    add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );                                     




                            }       


                            public function load_js() {
                                wp_enqueue_script(
                                        'dhlswedenjs',
                                        plugins_url('/js/wibergsweb.js', __FILE__)                                        
                                );

                                wp_localize_script( 'dhlswedenjs', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); //Frontend ajax url                                



                            }        



                            /**
                             * calculate_shipping function.
                             *
                             * @access public
                             * @param mixed $package
                             * @return void
                             */
                            public function calculate_shipping( $package = array() ) {
                                    $this->add_rate(
                                                array(
                                                        'label'   => $this->title,
                                                        'cost'    => 0,
                                                        'taxes'   => false,
                                                        'package' => $package,
                                                )
                                        );
                            }


                    }
            }
    }
    add_filter( 'woocommerce_shipping_methods', 'add_shipping_DHLSweden' );

        function add_shipping_DHLSweden( $methods ) {
        $methods['dhl_sweden'] = 'WC_Shipping_DHLsweden';
        return $methods;
    }
        add_action( 'woocommerce_shipping_init', 'dhlsweden_shipping_method_init' );


        function shippingmethod_template($template, $template_name, $template_path) {
            if ($template_name == 'cart/cart-shipping.php') {               
                $template = plugin_dir_path(__FILE__) . '/woocommerce/cart/cart-shipping.php';
            }
            return $template;
        }
        add_filter('woocommerce_locate_template', 'shippingmethod_template', 20, 3);        




}

I'm trying to figure out how to execute an ajax-call (Ive done this before but not in a "shipping-method-context")

My javascript-file looks like this:

$('#dhlsweden_delivery').hide();
$('#dhlsweden_button_shippinglocations').on('click', '', function() {

    var shipping_adr = $('#dhlsweden_shipping_adr').val();
    var shipping_postalcode = $('#dhlsweden_shipping_postalcode').val();

    alert(shipping_adr);
    alert(shipping_postalcode);

    var check_dhl_location = $.ajax({            
        type: 'POST',
        data:{
            action: 'checklocation',    
            dhlsweden_shipping_adr: shipping_adr,
            dhlsweden_shipping_postalcode: shipping_postalcode 
        },
        url: MyAjax.ajaxurl,
        dataType: 'json'
    });

    check_dhl_location.done(function(content_data) {
        alert('ok!');
        console.log( content_data );
    });

    check_dhl_location.fail(function(ts) {    
        alert('Något fallerade');

      alert(ts.responseText);
    });

});
3
  • Have you tried using the more modern/easier/debuggable REST API instead? The REST API tells you errors in readable plain language, unlike the ancient WP Admin AJAX that says nothing. It also implements a lot of security for you out of the box and gives you a pretty URL, e.g. /wp-json/foo/v1/bar, and works almost exactly the same on the frontend
    – Tom J Nowell
    Commented May 26, 2019 at 21:25
  • I would also strongly advise against defining a PHP class inside a PHP function, it will cause lots of problems
    – Tom J Nowell
    Commented May 26, 2019 at 21:26
  • @TomJNowell - Thanks for the tips. I did that way so I got the shipping method working. I understand now when you type that this is not a very good way of achieving this. Thanks for your input! Commented May 27, 2019 at 4:38

1 Answer 1

1

My guess is that the shipping method isn't initialised when you make an ajax call. Try moving your actions directly into your init function. EG:

function checkAjax(){
    print_r($_POST);
    exit;
}
function dhlsweden_shipping_method_init() {
    //use checkAjax since you don't have access to your shipping method class. If this is the case then you need to rework your code
    add_action( 'wp_ajax_checklocation', 'checkAjax' ); 
    add_action( 'wp_ajax_nopriv_checklocation', 'checkAjax' );  

    if ( ! class_exists( 'WC_Shipping_DHLsweden' ) ) {
        class WC_Shipping_DHLsweden extends WC_Shipping_Method {    
           ...
3
  • Thanks for your input! It's worth checking! I'll get back to you later! Commented May 27, 2019 at 4:38
  • Thanks for putting my in the direction. I had to move add_action ajax hook outside of the function! Thanks a lot! Commented May 27, 2019 at 4:45
  • 1
    Great, glad I could help :-) Commented May 27, 2019 at 23:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.