Asked  2 Years ago    Answers:  5   Viewed   80 times

I am creating a custom shipping method for Woocommerce using this tutorial https://docs.woocommerce.com/document/shipping-method-api/ but I am having issues debugging. Whenever shipping methods get updated by user, Woocommerce calls calculate shipping. I have overridden this function with the following.

public function calculate_shipping( $package ) {
    // This is where you'll add your rates
    $rate = array(
      'idea' => $this->id,
      'label' => $this->title,
      'cost' => '90.00',
      'calc_tax' => 'per_item'
    );
    echo "<script>console.log('Calculating shipping');</script>";
    $this->add_rate($rate);
  }

In the end I have a fairly complex way of calculating the "cost" but I have no way of debugging it because that echo line produces no output in the chrome console. Any ideas what is going on here?

Any help would be much appreciated. Thank you.

 Answers

3

As this is a background process on server side, don't use javascript.

1). WC Logs and the WC_Logger Class in WooCommerce for better debugging

To access the results of the log easily from the dashboard, you can log to a WC logger rather than the error log.

You can access error logs by going to WooCommerce > System Status > Logs.

Then you will be able to choose and "view"the error log file you need, giving you the debugging details that you need. Error logs are also located in the /wc-logs folder within your site install.

Running a stack trace on a caught exception (example):

// Log any exceptions to a WC logger
$log = new WC_Logger();
$log_entry = print_r( $e, true );
$log_entry .= 'Exception Trace: ' . print_r( $e->getTraceAsString(), true );
$log->log( 'new-woocommerce-log-name', $log_entry );

Notes:

  • WC_Logger methods have been updated since WooCommerce 3: So logging can be grouped by context and severity.

  • Use WC_Logger log() method instead of add() method due to upcoming deprecation (thanks to @Vizz85).

For example:

$logger = wc_get_logger();
$logger->debug( 'debug message', array( 'source' => 'my-extension' ) );

Related:

  • Develop WooCommerce blog (january 2017): Improved logging in WooCommerce 3
  • Documentation on the WC_Logger available methods

2). Debugging with WordPress WP_DEBUG Log (as an alternative)

a) First edit your wp-config.php file adding the following lines to enable debug (if these are already defined, edit the values):

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

As errors are logged, they should appear in wp-content/debug.log. You can open this file in a text editor.

b) On your code: Use the following (where $variable is the variable to be displayed in the error log:

error_log( print_r( $variable, true ) );

Now you will get the data for debugging.

Sunday, November 20, 2022
2

When setting up a Server the Host needs to match server host name. For my case I set server host to zrdn:

The web server needs to have the server name configured as well. In my case, I configured nginx like so:

server {
        listen   8080;
        server_name zrdn;
        ...

Thanks a million, @LazyOne!

Friday, November 11, 2022
 
etaoin
 
4

You shouldn't create a run configuration at all, just to click on the listen button:

  1. Configure xdebug to attempt to debug every single script (xdebug.remote_autostart = 1 and xdebug.remote_enable = 1).

  2. Use "Phone handle" icon in IDE to start listening for debug connections (e.g. as described in here)

  3. Launch your php code from anywhere -- XDebug will attempt to debug every incoming request.

Here is an hour long webinar about the subject.

bonus

if you're interested in doing the same thing on vi + xdebug, see this answer.

Friday, August 26, 2022
 
3

2020 Updated Answer

It is 2020 (7 years later) and I have learned more about Linux during this time. Specifically that it might not be a good idea to run sudo make install when installing libraries, as these may interfere with the package management system. (In this case apt as I am using Debian 10.)

If this is not correct, please correct me in the comments.

Alternative proposed solution

This information is taken from the GLFW docs, however I have expanded/streamlined the information which is relevant to Linux users.

  • Go to home directory and clone glfw repository from github
cd ~
git clone https://github.com/glfw/glfw.git
cd glfw
  • You can at this point create a build directory and follow the instructions here (glfw build instructions), however I chose not to do that. The following command still seems to work in 2020 however it is not explicitly stated by the glfw online instructions.
cmake -G "Unix Makefiles"
  • You may need to run sudo apt-get build-dep glfw3 before (?). I ran both this command and sudo apt install xorg-dev as per the instructions.

  • Finally run make

  • Now in your project directory, do the following. (Go to your project which uses the glfw libs)

  • Create a CMakeLists.txt, mine looks like this

CMAKE_MINIMUM_REQUIRED(VERSION 3.7)
PROJECT(project)

SET(CMAKE_CXX_STANDARD 14)
SET(CMAKE_BUILD_TYPE DEBUG)

set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)

add_subdirectory(/home/<user>/glfw /home/<user>/glfw/src)


FIND_PACKAGE(OpenGL REQUIRED)

SET(SOURCE_FILES main.cpp)

ADD_EXECUTABLE(project ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(project glfw)
TARGET_LINK_LIBRARIES(project OpenGL::GL)
  • If you don't like CMake then I appologize but in my opinion it is the easiest way to get your project working quickly. I would recommend learning to use it, at least to a basic level. Regretably I do not know of any good CMake tutorial

  • Then do cmake . and make, your project should be built and linked against glfw3 shared lib

  • There is some way of creating a dynamic linked lib. I believe I have used the static method here. Please comment / add a section in this answer below if you know more than I do

  • This should work on other systems, if not let me know and I will help if I am able to

Saturday, December 10, 2022
 
3

I just tested your code, and it seems to work:

  • On click, the ajax is made and my cart content is updated
  • the echo do_shortcode( '[woocommerce_cart]' ); is not working atm, as it thinks the cart is empty (and returns "empty cart" HTML message). But I don't see why you need the complete woocommerce cart HTML as a response here. Also, you use the response in tour JS as an object, but returning the do_shortcode will return a raw HTML string only.
  • the AJAX ends, and jQuery(document.body).trigger("added_to_cart") is called, which trigger the Woocommere cart fragment to refresh. As the AJAX call shortcode response is "wrong", the response object is not correct, but we can still trigger the event. Just make sure your custom listener handle the "no parameter" case
  • the cart fragment is refreshed, with your custom HTML

Take care about your <? endforeach; ?> that misses the <?php.

EDIT: After a quick test, it seems the woocommerce_cart shortcode output uses the woocommerce templates. So you could try to edit the Woocommerce Cart template files in your child theme to change the HTML output. (if you really need the cart HTML as the response to your custom ajax call).

Monday, September 5, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 

Browse Other Code Languages