3
\$\begingroup\$

I wrote PHP code to display a Woocommerce notice - "free shipping for $40 & under" only once on shop page and once on cart page, but also in cart should not be more than 40$. The code works, but i am not sure that it is the best way to do it:

$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

$shop_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") ."://$_SERVER[HTTP_HOST]/shop/";

$cart_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") ."://$_SERVER[HTTP_HOST]/cart/";

$first_time_shop = false;

if ((!isset($_COOKIE["mynoticeshop"]))&&($actual_link == $shop_link))
{
    $first_time_shop = true;
    setcookie("mynoticeshop", "mynoticesaleshop", time() + 600, $shop_link);
}
if ($first_time_shop) {
   function sp_custom_notice() {
        $subtotal = WC()->cart->subtotal;
        $free_shipping_threshold = 40;
        if ($subtotal < $free_shipping_threshold) {
        wc_add_notice( 'free shipping for $40 & under', 'notice' );
    }
}

add_filter( 'woocommerce_init', 'sp_custom_notice' );
}

$first_time_cart = false;
if ((!isset($_COOKIE["mynoticecart"]))&&($actual_link == $cart_link)) {
    $first_time_cart = true;
    setcookie("mynoticecart", "mynoticesalecart", time() + 600, $cart_link);
}
if ($first_time_cart) {
   function sp_custom_notice() {
        $subtotal = WC()->cart->subtotal;
        $free_shipping_threshold = 40;
        if ($subtotal < $free_shipping_threshold) {
        wc_add_notice( ' free shipping for $40 & under', 'notice' );
    }
}

add_filter( 'woocommerce_init', 'sp_custom_notice' );
}

I am new to Programming and I am interested to know if there is a better and shorter solution of this code?

\$\endgroup\$
  • \$\begingroup\$ cross-posted on SO \$\endgroup\$ – Sᴀᴍ Onᴇᴌᴀ Aug 8 '18 at 20:03
  • 1
    \$\begingroup\$ While it is great to know that you are accepting the feedback, please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers. \$\endgroup\$ – Sᴀᴍ Onᴇᴌᴀ Aug 9 '18 at 20:21
2
\$\begingroup\$

Don't Repeat Yourself

The D.R.Y. principle is a fundamental principle in programming. Anytime logic is repeated more than once, it should be abstracted. For example, the first three variable assignments contain the same ternary operation:

(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http")

That could be put into a function:

function GetProtocol() {
    return isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http";
}

That way if any of that logic needed to be updated, it could be changed in once place instead of three. The HTTP_HOST could also be included in that function - in that case, a name of GetProtocolAndDomain would be appropriate.

Like Peter's answer on SO mentions- the function sp_custom_notice() can be declared once, since the only difference between the two definitions appears to be the last line - where the first argument passed is 'free shipping for $40 & under' in the first case and the first argument is ' free shipping for $40 & under' in the second case. There isn't really a need for a space in the second case?

Peter also claims the first three variables are not necessary:

Firstly, you don't need the 3 $*_link variables as WooCommerce has 2 conditionals - is_shop() and is_cart() to check if you're on a shop page or a cart page. Also, the , $shop_link & , $cart_link in the setcookies aren't required, so you can safely get rid of them.1

This makes sense, since you can have the cookies available for all pages on the domain instead of just a single page. In the event that is_shop() and is_cart() weren't available, you could compare the last 5 characters of $_SERVER[REQUEST_URI] with cart/ or shop/ using substr() with -5 as the start parameter.

Threshold constant

It appears that the value for $free_shipping_threshold doesn't change. Because of this, it can be made a constant at the top of the file:

const FREE_SHIPPING_CONSTANT = 40;

Then that constant can be used in the sp_custom_notice function, and if that value needed to be updated, you could just look at the top of the file for the line to change.

Erroneous Line

I see the following line in your post:

$first_time_shop = true;<br>

Did you manually add the HTML break tag (i.e. <br>) when posting here? I would expect that if that was actually in your code then the PHP interpreter would thrown an error.

\$\endgroup\$
  • 1
    \$\begingroup\$ I added <br> tag when posting here :D thank you for help. I will improve the code. \$\endgroup\$ – Dima Vizelka Aug 9 '18 at 20:14
  • \$\begingroup\$ @DimaVizelka, I removed the HTML Tag because it is not needed for formatting on our site, but the space does not appear to be a result of formatting so it needs to stay in your post because it was mentioned in this answer/review. \$\endgroup\$ – Malachi Aug 9 '18 at 20:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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