Gerhard Potgieter

Senior Software Engineer @ Automattic specializing in eCommerce

WooCommerce 3.3: Hide uncategorize category from shop — February 9, 2018

WooCommerce 3.3: Hide uncategorize category from shop

In WooCommerce 3.3 we introduced a new uncategorized category all product will default to when no other category is assigned to them. This is the same behavior that WordPress uses for posts. With that, unfortunately, if your shop is set up to display categories on the shop page then this new uncategorized category will also show up.

Although we give you the possibility to rename the category to whatever you would like, there might be cases where you would like to rather not display this on your shop page. To do that you can simply add the following piece of code to your site via your theme’s functions.php file, or via a custom plugin. Remember to not include the opening tag<?php if you are adding this to an existing file.


<?php
add_filter( 'woocommerce_product_subcategories_args', 'remove_uncategorized_category' );
/**
* Remove uncategorized category from shop page.
*
* @param array $args Current arguments.
* @return array
**/
function remove_uncategorized_category( $args ) {
$uncategorized = get_option( 'default_product_cat' );
$args['exclude'] = $uncategorized;
return $args;
}

The Road To Getting FTTH In South Africa Part 1 — January 24, 2018

The Road To Getting FTTH In South Africa Part 1

This post forms part of a series of posts that I will be doing to document my journey to obtaining Fibre To The Home (FTTH) in South Africa.

It all started back in 2014, Fibre To The Home (FTTH) was a hot topic on all the tech news sites and you were reading about all these complexes and suburbs being connected. Now to give some background, I live in Brackenfell, a rather largish suburb in the north of Cape Town right next to Durbanville, even though the area is a popular area for residents to live in the chances at that time was very slim for an FTTH rollout as most of the rollouts were happing in estates and expensive neighbourhoods.

One day I noticed a team digging a trench opposite my house at the time, there were no houses on the opposite of our street and was separated by a small wall from the main road. I got a bit happy but that soon disappeared after speaking with the people to find out that the lines were Dark Fibre Africa (DFA) lines and are not an FTTH rollout. DFA basically provides Dark Fibre to other clients that need connectivity, more so business clients.

A couple of years past and more digging ensued by the likes of MTN and Vodacom but still no FTTH. Then in July 2016 I bought a new house in the same area. Shortly after moving into the new place I saw they were erecting a cellphone tower on the church grounds behind my home and thought they will surely need fibre to be laid to this tower. Being fed up with ADSL speeds of 6Mbps and connectivity issues due to aging copper infrastructure I decided to try and find a way to get Fibre at my new place.

After weeks of back and forth and numerous phone calls I finally found that the tower is a Vodacom tower and eventually got through to someone at DFA that put me in touch with an ISP that would be willing to install fibre to my premises, I was lucky enough that my house is only about 70m from the DFA connection point on the main road. There were some caveats though, I had to pay around R5k for the civil works to be done, which I thought was reasonable, but the thing that made me cancel the whole process was that they could only offer me a business package and I had to sign a 24 month contract which was around R4k pm for a 5Mbps fibre connection, and around R14k for a 100Mbps connection since they would only do these custom jobs for businesses.

Back to copper it was, but then in 2017 I noticed that Durbanville was being rolled out with Fibre through Vumatel and it would make sense for them to move into Brackenfell seeing as it is right next door. I searched some local groups on Facebook and used our neighbourhood watch and soon found out other people in the area that were also campaigning to get the area online. A couple of meetings later with the various neighbourhood watches in Brackenfell and Vumatel, we got our area approve for the show of interest phase of an FTTH rollout in August 2017.

Now how Vumatel works is they combine areas in a suburb into what they call a Fibrehood, then they start a show of interest phase, during that phase they need to get around 30% of residents in such a Firebhood to show their interest. If that is reached they start the planning and rollout phases. The thing is, because Brackenfell is so big, they divided it into 3 Fibrehoods, Brackenfell North, Brackenfell South, and Sonkring. At present only Brackenfell North and South has qualified, South’s rollout will start around the end of February 2018 and Sonkring still needs around 130 signups.

I got excited but was told if we could not reach the 30% target chances are slim we will get FTTH. At some point around October 2017 I got a bit worried as the numbers were just not climbing so I started to get in touch with people at Vumatel and offered to be a champion for my Fibrehood, there were already quite a lot of people campaigning but it was mostly through Facebook and it had limited reach. That is when I got the idea of trying a campaign per foot, I basically took a tablet with an internet connection and went door to door during the day and some evenings knocking and notifying residents about FTTH, the advantages and that we could be getting it. I probably signed up around 100+ residents while going per foot and registering them on the Vumatel site.

However, we were still around 150 signups short after that, luckily Vumatel informed me that they will also be doing flyer drops in the areas, a couple of weeks went past and then one day I got an email from my contact at Vumatel saying that our Fibrehood has qualified and we will have a townhall meeting on 9 November 2017.

I attended the townhall meeting where the residents were informed about how the whole FTTH rollout works, there were also quite a lot of ISPs at the townhall promoting their services, they were literally throwing themselves at the residents just to get a signup. The next day Vumatel marked our Fibrehood as “Build In Progress” on their coverage map and they also started the civil works on that day, a small team were spotted here and there, but the next Monday a couple of areas were covered in pink barriers with large teams busy digging which made it clear that things are happing.

Different areas the Brackenfell North Fibrehood has been devided into.

How Vumatel works during the rollout process are they divide a Fibrehood into different smaller areas, our area, Brackenfell North, are divided into 9 smaller areas. They only do work in certain areas at a time, I am part of area 6 and unfortunately did not fall into the first 2 area that they started in. I was quite impressed with the speed at which they were trenching and installing trunking, within in a matter of 3 weeks most of the 2 areas were closed up, and by the 10th of December, I spotted the Fusionoptics team making the splicing connections to the street cabinet for one of those areas.

That same day my area was full of pink banners and they started drilling holes underneath the driveways and roads, after speaking with some of the people on the street our area was going to be spared digging up driveways, they dig two big holes on either side of your driveway and then they used what they call a mole to drive a trunking pipe underneath the driveway eliminating the need to remove paving, tar etc. They dug the holes next to my driveway but then a couple of days later they returned informing me that my side of our street, unfortunately, need to have the driveways opened up due to a main cable that needs to run on my side of the street that is too big to fit into the trunking they do underneath the driveways.

On the 15th of December I was informed that construction had to be paused due to a law by the City Of Cape Town which prohibits any construction to take place during 15 Dec and 15 Jan. There I was another month having to wait without any progress, I was feeling a bit optimistic though as the map for our area showed an estimated completion date of Jan 2018.

12th of January 2018 approached and all of a sudden we have an influx of workers in our neighbourhood, I am talking literally around 200+ people with shovels all positioned around 10m apart for blocks digging, by that evening they were putting the fibre trunking in and filling up the holes for my street and a couple of other blocks, they were working quite late that day, especially the people in my street that dug up the driveways, by around 7pm I went and looked and they filled up my driveway. The next day, a Saturday, they were back putting up my wall box and putting my paving into place again and the following week they completed most of the restoration work. As of today I still have a small portion of paving missing which they are actually repairing as I am typing this, they were apparently waiting for stock of the colour of bricks I use.

Box mounted on wall from where the fibre core will be pulled into your home.

Today the 24th of Jan 2018, I took my usual morning stroll through the neighbourhood all the construction workers have pretty much left the area with trunking in place throughout. I also spotted a Fusionoptics van parked with people fiddling in the ground and wall boxes so I approached one of them and had a bit of a chat. They are the people that are actually blowing the fibre cable through the trunking and terminating it into the wall boxes, the gentleman was very polite and explained to me the process and showed me how they blow and connect a wall box up, he also showed me the fibre strands, literally like 2 pieces of hair that are inside a casing as thick as fishing gut that goes into 2 other protective trunking into your wall box and terminated to a pigtail. Having an interest in networking and some history with wireless networks I found it quite interesting and nice to see how they fibre process works compared to long-range wireless. He also informed me that they are aiming to have all the houses in our area connected up and live by end of next week Friday, 3rd of Feb 2018.

Each house gets one fibre casing consisting of two fibre strands capable of delivering up to 1Gpbs each.

So far I have been quite impressed with the speed of the rollout and their reinstatement work, there are some houses here and there that are waiting for some reinstatement work to be completed but from what I have heard that is due to the contractors waiting for supplies of certain bricks as was the case with mine. Vumatel has since updated the rollout map extending the estimated completion date for my area to Feb 2018 which seems like it might actually be live around mid February from what the people on the street tell me.

I placed my order with Vumatel shortly after they marked our area as in progress so I am all ready to get my line installed into my home. Initially I signed up with WebAfrica as my ISP since I currently have my ADSL through them and they were offering a free install package at the time, however after going through their TOS I found they are not truly month to month as they claim when you get the free install package and you are basically tied into a one year contract. That and reading some stories on MyBroadband about their Fibre service and throttling I decided to cancel with them and instead signed up with Cool Ideas.

Now Cool Ideas is a relatively new ISP to me, but after reading up on them and seeing all the feedback from the local tech community it persuaded me to choose them. They focus on Fibre Internet and have been ranked as the best Fibre ISP in South Africa two years in a row, they do not do any shaping or throttling, in fact, they do not even track usage at all on a customer level, if you are interested in knowing how much data you consume you will have to put your own data tracking in place. Their support seems to be top notch, they have a dedicated person on the MyBroadband forums attending to customer queries/issues and even do so during evenings, weekend and holidays, another plus!

Unfortunately, Cool Ideas does not offer any packages with free Vumatel installs, which I am okay with, but they do offer free activation and a free router all while providing a true month to month product. I also found out that should I wish I can choose to pay off the Vumatel installation over a 3 or 6 month period interest-free, which if you are on a budget and do not want to be tied into a contract with an ISP a great option.

Ceiling mounted Ubiquity Unify AC Pro Access Point.

After signing up with Cool Ideas I enquired what the free router is that they provide since my home is relatively large and I ordered a 100Mbps synchronous package I needed something that would be able to deliver the speeds to all my wireless devices while also providing adequate coverage throughout my home without affected the speeds. The router they provide is a TPLink WR840N consumer grade a/b/g/n router which was nothing cutting edge, same as my ADSL one which has coverage issues inside my house and a maximum wifi throughput of 300Mpbs. If you order their 200Mbps package they provide you with an AC capable router. Since I have roots in wireless networks with my past participation in CTWUG, I am fairly up to speed with enterprise WiFi and routing, AC WiFi was the way to go and after some research, I decided to go with Ubiquiti hardware. More specifically I went with the Edgerouter X as my router which has all sorts of functionality you can set up to do your own routing, QOS and usage tracking, and a Unifi AC Pro access point which is capable of delivering up to 1.7Gbps speeds over WiFi to devices capable of AC. I mounted it centrally in my house to the ceiling and getting speeds to the router not dropping below 300Mbps on the furthest points of my property which means it is adequate enough to max out my Fibre connection from any device on my property and leaves me with room to upgrade my fibre connection to 200Mbps which is the maximum speeds Cool Ideas are currently offering.

I am now all ready for my fibre installation once my area becomes fibre ready, I have existing trunking in place that leads from the pillar where my wall box is installed into my home which should make install day a breeze for the Nano Fibre team which handles all Vumatel’s installations. Stay tuned for part 2 where I will be documenting the actual installation into the home, and then part 3 where I will be wrapping up the series and providing some final tests and reviewing Cool Ideas as an ISP, perhaps also throw in a couple of tips and tricks in there that could speed up getting connected.

 

WooCommerce 3.2: Add back option to resend admin order email — October 13, 2017

WooCommerce 3.2: Add back option to resend admin order email

Since WooCommerce 3.2 the option to resend the admin new order email was removed. The reason was that it was a pretty much-unused feature as admins already have access to the orders so they could just look it up.

However, if you relied on this feature for some reason and now all of sudden can’t use it, fear not as it can easily be added back with the following snippet.

As always include the following code in your theme’s functions.php file omitting the opening <?php tags


<?php
/**
* This adds back an option to resend the admin new order email from the order edit screen that was removed in WooCommerce 3.2
*/
/**
* Filter to add a new menu to the dropdown
*
* @param array $actions
* @return array
*/
function add_resend_admin_order_email_action( $actions ) {
$actions['send_admin_order_details'] = __( 'Email order details to Admin', 'woocommerce' );
return $actions;
}
add_filter( 'woocommerce_order_actions', 'add_resend_admin_order_email_action', 10, 1 );
/**
* Hook into newly added send_admin_order_details to handle sending of admin emails
*
* @param $order Order object
* @return void
*/
function resend_send_admin_order_email( $order ) {
// Send the admin new order email.
WC()->payment_gateways();
WC()->shipping();
WC()->mailer()->emails['WC_Email_New_Order']->trigger( $order->get_id(), $order );
// Note the event.
$order->add_order_note( __( 'Order details manually sent to admin.', 'woocommerce' ), false, true );
do_action( 'woocommerce_after_resend_order_email', $order, 'new_order' );
// Change the post saved message.
add_filter( 'redirect_post_location', array( 'WC_Meta_Box_Order_Actions', 'set_email_sent_message' ) );
}
add_action( 'woocommerce_order_action_send_admin_order_details', 'resend_send_admin_order_email', 10, 1 );

view raw

functions.php

hosted with ❤ by GitHub

Installing PHPUnit on Mac OSX — October 12, 2017

Installing PHPUnit on Mac OSX

So you have an Apple Mac and want to get started in the wonderful world of Unit Testing. Writing a unit test is very straightforward, yet most open source software projects have very limited unit tests available so always welcome more and it could be an easy way to contribute to the project.

Like I said writing your first unit test is pretty straightforward, it can be something as simple as just checking if a constant is set $this->assertFalse( defined( 'WC_TESTING_DEFINE_FUNCTION' ) );. Yet when it comes time to run the actual test you quickly discover that you need to have some software installed on your machine to run this, PHPUnit in WooCommerce’s case.

Then you head over to https://phpunit.de/getting-started.html and copy and paste the command and find that it does not work on your Mac because Mac OSX does not ship with wget installed by default. Then you search for installing wget on your mac and you go into a deep rabbit hole of having to install all sorts of software just to get it working.

Luckily there is a simpler way, simply copy and paste the command below into your console to have PHPUnit installed.
php -r "copy('https://phar.phpunit.de/phpunit.phar', 'phpunit.phar');"
chmod +x phpunit.phar
sudo mv phpunit.phar /usr/local/bin/phpunit

WooCommerce: Hide refund reason from customers — October 9, 2017

WooCommerce: Hide refund reason from customers

Refunds can be a sore subject but it is something that every store has to deal with, keeping track of refund reasons can be very beneficial to you so you can keep pushing your refund rate down further and further.

The problem is that you do not always want your customer to see the reason you enter for when doing a refund, which WooCommerce will display by default to each customer.

Good news is that you can easily replace the refund reason in your customer-facing emails and pages with static text like just “Refund”.

Add the following code to end of your theme’s functions.php file omitting the opening <?php tag


<?php
/**
* Replace refund reason with generic Refund text.
*
* @param $total_rows
* @param $order
* @param $tax_display
* @return array
*/
function remove_public_facing_refund_reason( $total_rows, $order, $tax_display ) {
foreach ( $total_rows as $id => $row ) {
if ( false !== stripos( $id, 'refund_' ) ) {
$total_rows[ $id ]['label'] = __( 'Refund' );
}
}
return $total_rows;
}
add_filter( 'woocommerce_get_order_item_totals', 'remove_public_facing_refund_reason', 10, 3 );

view raw

functions.php

hosted with ❤ by GitHub

 

WooCommerce: Do not allow account creation with fake emails — November 16, 2016

WooCommerce: Do not allow account creation with fake emails

ECommerce is serious business, that is why when a customer signs up to your store you want the most accurate information to stay in touch, promote your products and offer decent after sales service. Unfortunately, there are lots of chancers out there on the internet that use fraudulent cards and fake emails to purchase products from your store, which can leave you to foot the bill.

The following piece of code will prohibit usage of fake emails for creating accounts, it focuses on sharklashers.com but can easily be expanded to include other email domains by just adding to the array.

Add the following code to end of your theme’s functions.php file omitting the opening <?php tag


<?php
/**
* Do not allow account creation with temp email addresses
* @param Object $validation_errors
* @param string $username
* @param string $email
* @return WP_Error
*/
function do_not_allow_temp_email_addresses( $validation_errors, $username, $email ) {
$prohibitied_domains = array(
'sharklasers.com',
'grr.la',
'guerrillamail.biz',
'guerrillamail.com',
'guerrillamail.de',
'guerrillamail.net',
'guerrillamail.org',
'guerrillamailblock.com',
'spam4.me',
);
$email_domain = explode( '@', $email )[1];
if ( in_array( $email_domain, $prohibitied_domains ) ) {
return new WP_Error( 'registration-error-bad-email', __( 'Please use a valid email address.' ) );
}
return $validation_errors;
} // End do_not_allow_temp_email_addresses()
add_filter( 'woocommerce_registration_errors', 'do_not_allow_temp_email_addresses', 10, 3 );

view raw

fake-emails.php

hosted with ❤ by GitHub

Uploading Files With wp_remote_post Or wp_remote_request — July 30, 2014

Uploading Files With wp_remote_post Or wp_remote_request

My job at WooThemes enables me to work on all sorts of cool projects and enables me to push the limits of what is possible with WordPress each day. Some of the projects I work on that I enjoy the most is projects that involves interfacing with any sort of API service, I am a sucker for an API 🙂

In a recent project which involved interfacing with an API service I had to upload a file to the service, and wanting to stay true to the WordPress way I naturally built the whole API interface layer using native WordPress functionality. This involved making use of the wp_remote_request function, which is called by the wrapper function wp_remote_post to send through POST requests.

After Googling for quite a while I just could not get any examples of uploading files in binary using wp_remote_post or wp_remote_request, for that matter, which resulted in me having to figure this out on my own.

The API document was straight forward, in order to upload a file you need to post it as binary to API endpoint, now there are plenty of example of doing this using cURL, so I used that as a starting point and converted it to WordPress native functionality.

The cURL way of uploading the file


curl -u username:password -H "Content-Type: application/binary" \
–data-binary @file.dat -X POST \
"https://domain.com/api/v2/uploads.json?filename=myfile.dat&quot;

view raw

curl.sh

hosted with ❤ by GitHub

Digging through some cURL docs I found that I basically needed to set a header to binary, and then stream the file binary content as the body, and found the following way of uploading the file using either wp_remote_request or wp_remote_post


<?php
// wp_remote_request way
$file = @fopen( 'path/to/file.txt', 'r' );
$file_size = filesize( 'path/to/file.txt' );
$file_data = fread( $file, $file_size );
$args = array(
'method' => 'POST'
'headers' => array(
'accept' => 'application/json', // The API returns JSON
'content-type' => 'application/binary', // Set content type to binary
),
'body' => $file_data
);
$result = wp_remote_request( 'https://domain.com/api/v2/uploads.json?filename=myfile.dat&#39; $args );
// wp_remote_post way
$file = @fopen( 'path/to/file.txt', 'r' );
$file_size = filesize( 'path/to/file.txt' );
$file_data = fread( $file, $file_size );
$args = array(
'headers' => array(
'accept' => 'application/json', // The API returns JSON
'content-type' => 'application/binary', // Set content type to binary
),
'body' => $file_data
);
$result = wp_remote_post( 'https://domain.com/api/v2/uploads.json?filename=myfile.dat&#39; $args );
?>

view raw

file.php

hosted with ❤ by GitHub

The above code shows examples of using either wp_remote_request or wp_remote_post, as you can see there is not much difference between the two, instead that with wp_remote_post there is no need to set the method header as it is a wrapper function that does that automatically.

In some cases API services will require you to do uploads with PUT requests instead of POST, in that case you will use the wp_remote_request function and just set the method header to PUT instead of POST to make a PUT request.

Hope this helps someone out there that has also struggled to do this using native WordPress functions.

 

 

 

WooCommerce 2.1 Add Confirm Password Field at Checkout — February 25, 2014

WooCommerce 2.1 Add Confirm Password Field at Checkout

WooCommerce 2.1 Confirm Password Field on CheckoutThe last couple of weeks I have spent a lot of time working on some tutorials to reverse some of the changes introduced in WooCommerce 2.1 to the ways it was in WooCommerce 2.0.

This tutorial is another one of this cases, WooCommerce 2.1 removed the password confirm field and functionality from the checkout page as it was thought that should a customer make a typo in the password field they can easily just reset it via the password reset functionality in WooCommerce.

However if you would still like add this password confirm field to your WooCommerce 2.1 checkout page, good news is this is still possible.

The code below will add an additional field underneath your password field on the checkout page called Confirm Password and when the customer places the order it will check the two password field against each other and give an error message and prohibit checkout if they do not match.

Place the code below in your theme’s functions.php file


<?php
// place the following code in your theme's functions.php file
// Add a second password field to the checkout page.
add_action( 'woocommerce_checkout_init', 'wc_add_confirm_password_checkout', 10, 1 );
function wc_add_confirm_password_checkout( $checkout ) {
if ( get_option( 'woocommerce_registration_generate_password' ) == 'no' ) {
$checkout->checkout_fields['account']['account_password2'] = array(
'type' => 'password',
'label' => __( 'Confirm password', 'woocommerce' ),
'required' => true,
'placeholder' => _x( 'Confirm Password', 'placeholder', 'woocommerce' )
);
}
}
// Check the password and confirm password fields match before allow checkout to proceed.
add_action( 'woocommerce_after_checkout_validation', 'wc_check_confirm_password_matches_checkout', 10, 2 );
function wc_check_confirm_password_matches_checkout( $posted ) {
$checkout = WC()->checkout;
if ( ! is_user_logged_in() && ( $checkout->must_create_account || ! empty( $posted['createaccount'] ) ) ) {
if ( strcmp( $posted['account_password'], $posted['account_password2'] ) !== 0 ) {
wc_add_notice( __( 'Passwords do not match.', 'woocommerce' ), 'error' );
}
}
}
?>

view raw

functions.php

hosted with ❤ by GitHub

WooCommerce 2.1 Grouped Prices Revert To WooCommerce 2.0 Format — February 24, 2014

WooCommerce 2.1 Grouped Prices Revert To WooCommerce 2.0 Format

WooCommerce 2.1 Grouped Product Prices, Revert to WooCommerce 2.0 Format

 

Last week I did a tutorial that showed you how to change your WooCommerce 2.1 Variation prices from the new range format to the old WooCommerce 2.0 From: format, that tutorial however only included changing the prices of variable products.

The following tutorial shows you how to modify the Grouped Product prices that also uses the new range format in WooCommerce 2.1 to the WooCommerce 2.0 From: format.

To change the pricing format for your WooCommerce grouped products add the code below to your theme’s functions.php file


<?php
// Place in your theme's functions.php file
// Revert grouped product prices to WooCommerce 2.0 format
add_filter( 'woocommerce_grouped_price_html', 'wc_wc20_grouped_price_format', 10, 2 );
function wc_wc20_grouped_price_format( $price, $product ) {
$tax_display_mode = get_option( 'woocommerce_tax_display_shop' );
$child_prices = array();
foreach ( $product->get_children() as $child_id ) {
$child_prices[] = get_post_meta( $child_id, '_price', true );
}
$child_prices = array_unique( $child_prices );
$get_price_method = 'get_price_' . $tax_display_mode . 'uding_tax';
if ( ! empty( $child_prices ) ) {
$min_price = min( $child_prices );
$max_price = max( $child_prices );
} else {
$min_price = '';
$max_price = '';
}
if ( $min_price == $max_price ) {
$display_price = wc_price( $product->$get_price_method( 1, $min_price ) );
} else {
$from = wc_price( $product->$get_price_method( 1, $min_price ) );
$display_price = sprintf( __( 'From: %1$s', 'woocommerce' ), $from );
}
return $display_price;
}

view raw

functions.php

hosted with ❤ by GitHub