Pop Quiz! osCommerce. Lets see how good you are…

So, this image shows a SQL command that I have amended from the original;

Can you answer these questions;

1. In which file can the original SQL be found?
2. What add-on have I added to this particular site? Please provide a link to the add-on…
3. What change(s) did I make to the SQL, and for what purpose?

I’ll think up a suitable prize for the first to get all 3 questions mostly correct. Or I might not, as it’s just a bit of fun.

Google Breadcrumb Links for osCommerce

Recently, a reader of clubosc, “Snowbird” brought up an interesting diversion based on one of my previous posts about changing the breadcrumb in osCommerce.

I did not know that Google sometimes shows breadcrumbs as part of the Search Engine Results Page (SERP), like so;

The breadcrumb part is the bottom line (in green). Note that the example is a result from Türkiye Google (Turkish Google), but can also be seen on the main google site as well as UK and many other Googles.

How to recreate this in osCommerce?

After some fiddling with code, I found that the simplest way is to use Googles examples as detailed here, the RDFa format is the easiest and involves changes to only 1 file!

Open up /includes/classes/breadcrumb.php and change the trail function as shown below;

Easy as that. I’ve also pasted the function here and if you want you can download the whole new breadcrumb class file here.

The changes really don’t do anything to your design, they only give Google the code it needs to determine that these links are to be used to produce a breadcrumb within your search listings.

Easy as 123. Of course, I give no guarantee that this change will do any good to your search results, please let me know if any of you change your breadcrumb and if Google then picks it up and displays as a breaded list of links in your SERP. Thanks.

Add Order Number to Invoice – osCommerce

A client wanted to add the order number to the invoice, so it shows like this;

It’s a pretty simple change, as shown below;

Remembering to also create the constant for the language;

Done!

Then I was asked to “pad” the Order Number with a bunch of leading zero’s. My first idea was to simply add in some zero’s like this;

Order Number: 000006

So the code would read;

[php]

00000

[/php]

But of course, this would not work as intended as there would always be 5 leading zeros, whereas it would look better to have 4 leading zeros in the 100’s and 3 leading zeros in the 1000’s – so….

000006
000066
000666
006666
and so on. By simply adding 5 leading zero’s I would get;

000006
0000066
00000666

etc. So, a quick look at the PHP site and I see that str_pad is the correct way to do this. Here’s the code;

[php]

[/php]

In this code I am saying that the Order Number ($oID) must be at least 6 digits long. If it less than 6 digits, then it is padded to the left (ie, preceeding the Order ID) with as many zeros as it takes to make the Order ID 6 digits. Hope that makes sense.

Anyway, I end up with exactly what is wanted! Which is always good.

Facebook “LIKE” on your osCommerce shop

Jan asks;

possible to put the new like button on osc

Yep, and it’s super simple, using this quick and dirty code.

Step 1: Add this code to your header, footer, or wherever you want the like button to show;

[php]here.

Step 3: Add this code to the bottom of either /includes/footer.php (pre rc3) or includes/template_bottom.php (rc3), making sure to substitute “your app id” with your actual app id;

[php]


[/php]

Done.

Code needs to be cleaned up for real use, but this should give you enough of an idea to be able to do what you need to do.

osCommerce -> Admin -> Manufacturers -> BUG -> Fixed

I’ve been working on the manufacturers page of the osCommerce Admin section to get some “proof of concept” code working.

Whilst working on it, I couldn’t understand why the manufacturers image kept disappearing. On closer inspection I found some buggy code which I have now fixed.

Github Commit.

Basically, the image was uploading nothing, and overwriting the existing image if a Manufacturer was edited (eg, changing the name, adding a URL etc).

If you don’t understand Github, here’s the fix;

Find this:

[php]if ($manufacturers_image = new upload(‘manufacturers_image’, DIR_FS_CATALOG_IMAGES)) {
tep_db_query(“update ” . TABLE_MANUFACTURERS . ” set manufacturers_image = ‘” . $manufacturers_image->filename . “‘ where manufacturers_id = ‘” . (int)$manufacturers_id . “‘”);
}[/php]

Change to this:

[php]$manufacturers_image = new upload(‘manufacturers_image’);
$manufacturers_image->set_destination(DIR_FS_CATALOG_IMAGES);
if ($manufacturers_image->parse() && $manufacturers_image->save()) {
tep_db_query(“update ” . TABLE_MANUFACTURERS . ” set manufacturers_image = ‘” . $manufacturers_image->filename . “‘ where manufacturers_id = ‘” . (int)$manufacturers_id . “‘”);
}[/php]

This bug definitely exists in all versions of osCommerce upto and including the latest Github release of rc3. I have not tested manufacturers in osC v3.

Using cURL instead of file functions

Some hosts don’t allow the possibility of using the file functions that are built into PHP.

A URL can be used as a filename with this function if the fopen wrappers have been enabled.

So, if the fopen wrappers are turned off, you have no chance of using an external URL to get information (an example would be to get shipping rates from a 3rd party in order to calculate the correct postage).

So, I’m going to show you how I updated a clients codebase to use cURL…it’s really easy.

Background

The non-working portion of code is this;

[php]$url = “http://drc.edeliver.com.au/ratecalc.asp?Pickup_Postcode=$frompcode&Destination_Postcode=$topcode&Country=$dest_country&Weight=$sweight&Service_Type=AIR&Height=$sheight&Width=$swidth&Length=$slength&Quantity=$shipping_num_boxes”;
$myfile = file($url);
foreach($myfile as $vals)
{
$bits = split(“=”, $vals);
$$bits[0] = $bits[1];
}[/php]

This is basically setting some parameters and requesting a file from AUS POST (an Australian Postage Company). The file contains text which delivers the postage rate to be charged, and some other info that we don’t need.

However because my clients host has the fopen wrappers turned off this was producing an error a bit like this;

Warning: file() [function.file]: URL file-access is disabled in the server configuration in public_html/includes/modules/shipping/auspost.php on line 68

I tried a couple of ways to get around this using htaccess or php.ini, but neither of these worked. So my only option was to recode the problem area of the module to make it use cURL.

You can check if cURL is installed on your server by using the server page in your osCommerce Admin Area. As I had not used cURL before, I spent a little familiaring myself with it, and then just jumped into the code feet-first. With a little tinkering I got it to work.

cURL

You can read more about cURL here. The basic idea is to open up a connection from your site to another, grab the needed values and then close the connection.

Code Changes

Step 1. Initialize the cURL session

[php]$my_curl = curl_init();[/php]

This is easy enough to understand, I’d have thought.

Step 2. Set the URL of the page to be opened

[php]curl_setopt($my_curl, CURLOPT_URL, ‘http://drc.edeliver.com.au/ratecalc.asp?Pickup_Postcode=’ . $frompcode . ‘&Destination_Postcode=’. $topcode .’&Country=’. $dest_country .’&Weight=’. $sweight .’&Service_Type=AIR&Height=’. $sheight .’&Width=’. $swidth .’&Length=’. $slength .’&Quantity=’. $shipping_num_boxes);[/php]

Again, this is easy enough. It’s the same code as the problematic codebase – but set out slightly differently as I prefer my code like this.

Step 3. Ask cURL to return the results in a variable

[php]curl_setopt($my_curl, CURLOPT_RETURNTRANSFER, 1);
$my_contents = curl_exec($my_curl);[/php]

At this point, $my_contents consists of the text that is returned by Aus Post. Which is problematic, as we need to get it into an array for useable purposes! But first, let’s close the cURL connection;

Step 4. Close the connection

[php]curl_close ($my_curl);[/php]

Step 5. Get the $my_contents into an array

[php]$my_contents = explode(” “, $my_contents);[/php]

Here we are “exploding” the text in the variable using a space.

Step 6. Use the individual array pieces as needed

[php]foreach($my_contents as $vals)
{
$bits = split(“=”, $vals);
$$bits[0] = $bits[1];
}[/php]

This was part of the standard codebase, but I have made it use $my_contents to work with.

So, the full new cURL code goes like this:

[php]$my_curl = curl_init();
curl_setopt($my_curl, CURLOPT_URL, ‘http://drc.edeliver.com.au/ratecalc.asp?Pickup_Postcode=’ . $frompcode . ‘&Destination_Postcode=’. $topcode .’&Country=’. $dest_country .’&Weight=’. $sweight .’&Service_Type=AIR&Height=’. $sheight .’&Width=’. $swidth .’&Length=’. $slength .’&Quantity=’. $shipping_num_boxes);
curl_setopt($my_curl, CURLOPT_RETURNTRANSFER, 1);
$my_contents= curl_exec($my_curl);
curl_close ($my_curl);

$my_contents= explode(” “, $my_contents);
foreach($my_contents as $vals)
{
$bits = split(“=”, $vals);
$$bits[0] = $bits[1];
}[/php]

I hope that this made some sort of sense and will help anyone in the future. There are lots of cURL tutorials available if you want more detailed information. Good luck!

Please note, that I am nowhere near knowledgable on cURL, and this post is just to show that it can be done, and done quite easily by anyone with just a little PHP knowledge and the ability to search Google.

Password Masking osCommerce

Quite a while back, I was part of a discussion on a forum (not the osCommerce forum) about Jakob Neilsen’s ideas on password masking. You can read Mr Neilsen’s thoughts here).

My idea was that his thoughts are valid, and are based on usability. My opinion is that 90% of users don’t need to have the passwords starred out (as there is no-one with them at the time of filling in a form). Note that I do not agree with some of the bunkum that Neilsen spouts!

Anyway, fast forward 6 months and whilst searching Google for something entirely unrelated, I found this blog post. So, why not give the option of having your users password fields starred or not?

With a bit of copy and paste, I got this into osCommerce on the create_account and login page.

All rather easy, and less than 5 minutes work!

All credits to Jakob Neilsen and to a fellow Devonshire Developer John Whish.

Only 1 product at a time in osCommerce

Over at the official osCommerce forum, someone asked about the possibility of only allowing a buyer to select 1 of each product.  My answer was to amend the display of the shopping cart and the shopping cart class…

It’s fairly easy.  What I am going to show you is amending the display using HTML and CSS, then a bit of PHP code to only add 1 of a product in the class file.

Step 1:  Make the quantity box readonly and look nicer.

As someone who has done a lot of HTML over the years I know that the attribute called “readonly” makes an input “read only”!  So I add this to the shopping cart page.  Open up shopping_cart.php and find

[php]’text’ => tep_draw_input_field(‘cart_quantity[]’, $products[$i][‘quantity’], ‘size=”4″‘) . tep_draw_hidden_field(‘products_id[]’, $products[$i][‘id’]));[/php]

Change it to:

[php]’text’ => tep_draw_input_field(‘cart_quantity[]’, $products[$i][‘quantity’], ‘size=”4″ id=”clubosc” readonly=”readonly”‘) . tep_draw_hidden_field(‘products_id[]’, $products[$i][‘id’]));[/php]

You can see that I have added the readonly attribute and given it a css ID called “clubosc”.

Step 2:  Amend the look of the box using .css

Open up stylesheet.css and add this code;

[php]#clubosc {
border: none;
text-align: center;
background: transparent;
}[/php]

Add something to the cart and your quantity box now looks like this:

Whereas the usual look is like this:

Now, because we have made the contents of the quantity field readonly, we have to ensure that not more than 1 product can be added. At the moment a buyer could return to the product page, and click “buy” again, ending up with 2 of the same item in his cart.

Step 3: Making only 1 buyable…

Open up /includes/classes/shopping_cart.php and find this line of code:

[php]$this->update_quantity($products_id_string, $qty, $attributes);
} else {
$this->contents[$products_id_string] = array(‘qty’ => (int)$qty);[/php]

Simply change both $qty to (int)1. So you end up with;

[php]$this->update_quantity($products_id_string, (int)1, $attributes);
} else {
$this->contents[$products_id_string] = array(‘qty’ => (int)1);[/php]

And that is it. 3 easy steps to allow customers to only buy a maximum of 1 of each product.

osCommerce Quiz?

An osCommerce Quiz for you to think about;

[php]
switch (tep_get_zone_code($order->delivery[‘country’][‘id’], $order->delivery[‘zone_id’], ”)) {
case ‘HI’:
case ‘AK’:
$extra_cost = ($cart->show_total() * (13/100));
break;
default:
$extra_cost = 0;
switch ($order->delivery[‘country’][‘iso_code_2’]) {
case ‘US’:
$extra_cost = 0;
break;
default:
$extra_cost = ($cart->show_total() * (13/100));
}
}
[/php]

And then an extra piece of code like this, elsewhere in the file…

[php]+ $extra_cost[/php]

I came up with proof of concept code (proof of concept is just that, it shows it work but might not be the most graceful codebase) to illustrate something. Thought it might be interesting for you guys to see some code with no explanation, and find out what the code is for.

So, questions;

1. In which file(s) could this code be placed?
2. Which country/countries add NO cost?
3. Which states add an extra cost?
4. What is the extra cost?

New, Used, Refurbished in osCommerce Product Info

Interesting code question posed on the osCommerce forum so I thought it would make a decent blog post;

Are there any contributions out there which add product information fields in the admin section so that you can list the product as new, used, or refurbished?

Always self code if possible, it’s better and you learn a little bit about the osCommerce engine…

Step 1: Add new input fields to admin/categories.php

Easy enough, basically look at produce model, and copy the code but rename to product_type. Add an extra question in the form;

[php]



[/php]

Next up, an ugly kludge to read the value of each of the options and check the correct one automatically (eg, if you are updating an existing product).

[php]products_type == 0) ? true : false;
$checked1 = ($pInfo->products_type == 1) ? true : false;
$checked2 = ($pInfo->products_type == 2) ? true : false;
?>[/php]

Step 2: Add language definitions to admin/includes/english/categories.php

I’m sure you can see what you need to add, from the code above!!!

Step 3: Add new row to DB products table

Add a row called products_type, and make it a smallint of 2 characters (this gives you upto 99 different types in case you need to expand this in the future.

DONE! Here is how it looks;

Now you can do more stuff, how about showing the type of product on the product_info.php page? Certianly possible, but quite complicated as you need two new functions along with a sprintf. But, easy enough, here’s how it looks;

I can maybe show how I did that in a future post, if there is any interest. But if you want to try yourself, here is a few clues;

1. Because all we have in the database is “0” or “1” or “2”, you need to link those numbers to text, so 0 = new, 1 = Old and so on.
2. Once you’ve done that you need to use a sprintf to show some text along with the number.
3. And make a function to change the number into the text that it is linked to.

Remember that this is a quick and easy way of doing this – coded by me in less than 10 minutes – so it might not do everything that you need it do! But it’s a good start on a coding adventure. Good luck!