Learned today: Apache strips Authorization header

TL;DR: CGIPassAuth On

The problem was that WordPress Rest API was not getting the HTTP basic auth information in the request. In this RunCloud setup there is first Nginx, which proxies to Apache, which proxies to FastCGI, which runs PHP ( I suppose the only reason Apache is there is to support .htaccess files).

First I suspected Nginx, because I’ve recently had issues with Nginx not always forwarding request headers to upstream host. I added  proxy_pass_request_headers on there, but it made no difference.

I created a test script that prints out the Authorization header, and indeed it was not getting all the way to PHP. Some other headers, like User-Agent were getting through.

I checked the Apache access logs, and the username was not getting printed there, so I thought that Apache is not getting the header.  I tried making the request directly to Apache, bypassing Nginx, but my test script still wasn’t getting the header. That lead me to suspect either Apache or PHP.

Finally I managed to find a Stack Overflow answer that lead me to the solution. I added CGIPassAuth On to .htaccess and bingo! Problem solved.

WordCamp Jyväskylä

Today I attended WordCamp Jyväskylä, a one-day event focused on WordPress, mostly from developer’s point of view this time. The event had presentations on two tracks, and it was difficult to choose which track to attend as both tracks had interesting presentations.  I chose these presentations / workshops:

Issue with WordPress text widget, Black Studio TinyMCE Widget and icl_sw_filters_widget_text

We had a problem where the text of plain old WordPress text widgets was not showing on pages. Error log showed entries like

[13-Dec-2017 09:25:29 UTC] PHP Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'icl_sw_filters_widget_text' not found or invalid function name in /home/itukylat/public_html/wp-includes/class-wp-hook.php on line 288

Function icl_sw_filters_widget_text is defined in WPML String Translation plugin, but we didn’t have that installed. The only place where I could find hook to icl_sw_filters_widget_text being added is in Black Studio Tiny MCE Widget plugin, in black-studio-tinymce-widget/includes/class-compatibility-plugins.php, function wpml_widget_after:

if ( false === has_filter( 'widget_text', 'icl_sw_filters_widget_text' ) && function_exists( 'icl_sw_filters_widget_text' ) || version_compare( $this->wpml_get_version(), '3.8.0' ) >= 0 ) {
    add_filter( 'widget_text', 'icl_sw_filters_widget_text', 0 );
}

and indeed that gets called, even though there is no icl_sw_filters_widget_text function anywhere.

I suspect there is something wrong with the if statement, but I didn’t dig any deeper. But I did report the issue to Black Studio Tiny MCE Widget author.

Meanwhile, as a workaround I defined my own icl_sw_filters_widget_text function:

function icl_sw_filters_widget_text($text) {
    return $text;
}

Now the texts in text widgets show up again.

How to restore price suffix for variable product in WooCommerce

WooCommerce does not show price suffix for variable products if the suffix contains placeholder variables. The reason is explained in the comment of WC_Product_Variable::get_price_html method:

Note: Variable prices do not show suffixes like other product types. This is due to some things like tax classes being set at variation level which could differ from the parent price. The only way to show accurate prices would be to load the variation and get IT’s price, which adds extra overhead and still has edge cases where the values would be inaccurate.

If you still want to show the price suffix just like for normal products, do as Mike Jolley laconically says in this issue report:

Use the filter in that method if you want to force it programmatically.

So, here is my take on what that filter would look like:

add_filter('woocommerce_get_price_suffix', function ( $html, $product, $price, $qty ) {
     if ( ! $html && $product instanceof WC_Product_Variable) {
         // Copied from plugins/woocommerce/includes/abstracts/abstract-wc-product.php#get_price_suffix
         if ( ( $suffix = get_option( 'woocommerce_price_display_suffix' ) ) 
             && wc_tax_enabled() 
             && 'taxable' === $product->get_tax_status() 
         ) {
             $replacements = array(
                 '{price_including_tax}' => wc_price( wc_get_price_including_tax( $product, array( 'qty' => $qty, 'price' => $price ) ) ),
                 '{price_excluding_tax}' => wc_price( wc_get_price_excluding_tax( $product, array( 'qty' => $qty, 'price' => $price ) ) ),
             );
             $html = str_replace( array_keys( $replacements ), array_values( $replacements ), ' <small class="woocommerce-price-suffix">' . wp_kses_post( $suffix ) . '</small>' );
         }
     }
 
     return $html;
}, 10, 4);

 

Hello world!

I finally got myself to set up this site where I can post about the things I’ve learned on software development, and other things related to my professional life.

Because I know WordPress pretty well due to working at Wysiwyg Oy, a digital agency focused on WordPress, I decided to use it on this site as well. I just wanted to get this up and running, instead of learning yet another, possibly cooler content management system.