Product Lists in osCommerce

Some time ago on one of my other blogs, I spoke about my frustration with how osCommerce lists products. It’s a mish-mash of 4 or 5 different ways.

To see what I am talking about have a look at this (New Products for Month), then this (New Products Page), then this (Products of a certain Manufacturer) and finally this (Advanced Search Results).  You can see the difference in the looks straightaway.

My idea is to get a standardised look for all lists.  So what I am going to attempt to do is to use one module to create all the lists – in this way, we know that any lists of products will look the same where-ever you are in the store.

I’ve been working on this off and on for some while (admittedly more “off” than “on” but there you go), and have so far managed to get the following lists standardised:

1. new products for “month” (in the index page)
2. category drilldown lists
3. sub-category drilldown lists
4. manufacturer lists (needs further coding to add “paging”)
5. advanced_search_results list (however, this needs further coding to add “paging”)

I still need to recode products_new.php to use the module rather than it’s own mishmash of code.

More lists

I can think of the “shopping_cart.php” list (eg, when having 2 or more items in cart), but this would need to stay as is, as it needs extras such as “remove” column, “quantity” column etc.

What other lists are there in osCommerce – off the top of my head, I can’t think of any more.  Can you?

Seeing the results

Once I have all the lists covered, I’ll introduce the new module as a contribution – in my opinion it’ll be much more useful to have the look of the lists standardised across all osCommerce pages.

Are you an existing customer?

I suspect that most store owners would like their customers to purchase more than once – I know that I like people to purchase my products as often as possible!

I’ve never really explored the avenue of “returning customers” to any great degree. My idea this morning is to optimise the checkout (covered in a previous post!). A quick summary:

1. person presses “pay now” (aka checkout)
2. they go to account creation page (rather than the login page) – I feel that the account creation page is less “in your face” that a login page.
3. They create an account and checkout as normal.

Now, my idea is to set a lifetime cookie in the “create_account” process. This cookie will simply show that the person using the computer has already created an account. The next time that they come to buy something from the shop, the cookie will get read and instead of the “pay now” redirecting to “create_account”, it will redirect to “login”…

Note that the cookie will hold no identifiable information such as email address or password etc – just a simple falg to say whether or not an account has been made already.

Does anyone see a downside to this idea?

Let’s see what we have here

“Let’s see what we have here” – a piece of text that shows as the title in each of your category pages. Absolutely useless! You should change this to something more interesting and useful (in terms of user experience and SEO) such as the title of the category – doing this is very simple…

Open up /includes/languages/english/index.php and find:

[php]define(‘HEADING_TITLE’, ‘Let\’s See What We Have Here’);[/php]

Change to:

[php]define(‘HEADING_TITLE’, $categories[‘categories_name’]);[/php]

Save and upload. Done.

There is a slight problem once you’ve done this, but I’ll cover that in a future post – inthe meantime I wonder if any of you can work out what the problem is? The first person to spot the problem and present a solution will win a prize…

Answer to Problem:

[php]$category_name = (isset($HTTP_GET_VARS[‘manufacturers_id’])) ? $manufacturers[‘manufacturers_name’] : $categories[‘categories_name’];
define(‘HEADING_TITLE’, $category_name);[/php]

manufacturers are now called as appropriate.

Nested Tables in osCommerce

Because osCommerce was originally conceived in the late 90s/early 00s it was written without much thought to the underlying codebase – which is why everything is created using “tables”. So, I thought it might be nice to have a recurring series of posts showing how to get rid of some of the tables from osCommerce.

Why would you want to do this?

For starters, pages with less code will show faster in peoples browsers – these days, with lots of people having broadband, it’s not so important. Another reason would be for accessibility and usability – both very important these days. And, another reason, is just to make pages easier to understand (underneath the hood). And, possibly the most important reason – make our code more semanticvally correct which will benefit SEO (Search Engine Optimisation)

Let’s start with a simple page – shipping.php

These basic “info” pages, are solely used for showing information – so it’s easy to visualise the code. These pages show 3 things:

1. HEADING_TITLE (the heading – from the language file)
2. TEXT_INFORMATION (the content that is inserted in the “language” file)
3. A button that allows the reader/user to return to the default index page.

For these three items, I count five tables only being used for “alignment” purposes. So let’s get rid of them.

The code

Find this:

[php]

‘ . tep_image_button(‘button_continue.gif’, IMAGE_BUTTON_CONTINUE) . ‘‘; ?>

[/php]

Change it to this:

[php]

‘ . tep_image_button(‘button_continue.gif’, IMAGE_BUTTON_CONTINUE) . ‘‘; ?>

[/php]

Find this:

[php]

[/php]

Change it to this:

[php][/php]

Find this:

[php]

[/php]

Change it to this:

[php]

[/php]

So that the middle bit of the file now looks exactly like this:

[php]

[/php]

As you can plainly see, we’ve reduced the codebase by a good 25 or so lines of code already. The next thing that we need to do is open up stylesheet.css and add this:

[php]#button { text-align: right; padding-right: 10px; }[/php]

This will align the button to the right and indent it a little from the right hand side – so it looks just as it should compared to “normal” oscommerce.

How easy was that to remove 25 lines of code from just 1 file. If you could do this across the rest of the 40 or so “base files” (being product_info.pgp, index.php etc) you’d save yourself around 1000 lines of useless, unwanted, unneeded code.

In future posts I’ll look at other areas where code can be saved – including the functions, classes, modules, boxes and so on. I know that over time, we can recode the entire oscommerce codebase and save THOUSANDS of lines of code.

Add an icon to shipping quotes in osCommerce

This is a super simple little modification that you can use to draw attention to your preferred method of shipping…

What we are going to do is add an icon to the “flat rate” quote, so that instead of looking like this:

It will look like this:

Step 1: Make your icon

This is easy enough – just make or acquire an icon. In the example above I used a “star” image, but you could use any image you wish.

Step 2: Upload your icon

The icon you made should be uploaded into your “icons” directory which is inside your “images” directory. It’s important to remember what you called the icon – I called mine star.jpg

Step 3: Code changes

Open up /includes/modules/shipping/flat.php and find this line of code:

[php]$this->icon = ”;[/php]

Change it to:

[php]$this->icon = DIR_WS_ICONS . ‘name_of_your_file’;[/php]

In my example, I had to change it to:

[php]$this->icon = DIR_WS_ICONS . ‘star.jpg’;[/php]

Save the file and upload. All being well, your image should now show. Easy as 123.

A little explanation of the line of code…

[php]$this->icon = DIR_WS_ICONS . ‘star.jpg’;[/php]

We are simply telling the software to look inside DIR_WS_ICONS (/images/icons/) for a file called star.jpg – and assign the image to $this->icon

Later on in the flat.php file, $this->icon is used to show the image…

[php]if (tep_not_null($this->icon)) $this->quotes[‘icon’] = tep_image($this->icon, $this->title);[/php]

Which might not make any sense to you, but that doesn’t matter. All you need to know is that if you did everything correctly, your image file will show up.

You can make this same change to any of your shipping methods – eg, you might use “Royal Mail Special Delivery” so you might want the SD logo. Have fun!

Deconstructing an osCommerce Shipping Module

Shipping is just about the easiest thing to learn to code in osCommerce – what I am going to do in this post is deconstruct a shipping module so that you learn a little bit about how it works…

The module we are looking at is /includes/modules/shipping/flat.php – starting from the bottom I will attempt to explain each “function”.

[php]function keys()[/php]

This function returns some values from the database. These values are determined by the “install” function.

[php]function remove()[/php]

This function removes (which is why it is called “remove”!) values from the database when you uninstall the module from within your admin section.

[php]function install()[/php]

This function, guess what, install values to the database when you install the module from within your admin section.

[php]function check()[/php]

This function checks the values in the database that are linked to the module.

[php]function quote($method = ”)[/php]

This function outputs a shipping quotation to the checkout_shipping.php page if the module is installed.

[php]function flat()[/php]

This is the main “parent” function that controls all the other functions and passes information to those functions.

[php]class flat[/php]

The overall class, which allows us to use the above functions logically.

Classes are nothing more than a collection of variables and functions acting on those variables. They provide a means of thinking about things in real world terms. In other words they describe an object. An object, or instance, of a class is an actual “living, breathing” structure of that class. Let’s say we want to describe a bicycle. A proper class of a bicycle might have the variables $pedals, $chain, $front wheel, $rear wheel, $brakes, and $handle_bars. Functions of the bicycle would include Stop(), Accelerate(), Coast(), TurnLeft() and TurnRight(). You can think of your script as the entity operating that bike. The function Accelerate() could be passed an argument such as $Braking_Force and use that information along with the defined instance variables (probably $brakes and $wheels) and output some result back to your script.
For more reading on classes, click here (external link to phpbuilder.com).

Changing Text in Shipping Modules

Some things that are in UPPER CASE, like this MODULE_SHIPPING_FLAT_TEXT_TITLE is a defined piece of language…which means that it can be changed in the linked language file – NOT in the actual shipping module. The language files are found within the languages structure – for “flat.php”, the language file is at;
/includes/languages/english/modules/shipping/flat.php – simply change the wording to reflect what you want on the page. If you wanted to change the description from “best way” to “1 set cost for all products”, you would change this:

[php]define(‘MODULE_SHIPPING_FLAT_TEXT_WAY’, ‘Best Way’);[/php]

to this:

[php]define(‘MODULE_SHIPPING_FLAT_TEXT_WAY’, ‘1 set cost for all products’);[/php]

Other things that are in UPPER CASE are found in the database – it was added when we installed the Module using the “install” function. These are controlled from within your Admin section.

I hope that this short blog post was useful – in the future I will create a shipping module from scratch and show you how it’s done. If anyone has an idea for a shipping module, please comment below.

YOUR oscommerce site on YOUR home computer

I’m now offering a new service whereby I “mirror” your live oscommerce site onto your own home computer.

There are many reasons why you would want to do this, one of the most important being the fact that you will always have a backup should any of your live files become corrupted.  You also will be able to test new contributions, make design changes etc on your “mirror” site before transferring the changes to your live site.

They say an image is worth 1000 words, so there you go.  I take your live site, and transfer it into a system which can be used on your own home computer.  There is no link between the “live site” and the “mirror site” – so you are safe to make whatever changes you wish on the “mirror site” – once happy, you can then transfer your changes to “live”.  Easy as 123.

The cost of this service is £15.00, payable by Paypal.  The service is for Windows PC users only – and Mac users who can run a windows emulator.

If you are interested, and I don’t see why you would not be, please get in touch, my email address is up there ^

Every osCommerce user, and I really do mean EVERY osCommerce user should have their site mirrored in case of emergency.  And now, this service can make it happen, easily, quickly and without fuss.  If the cost is too much, get in touch anyway, as I have another option that you might like to know about!

Recording IP address in osCommerce

Alan asks;

Is it possible to record the ip address of each sale?

Alan, yes it is. But it is not standard osCommerce procedure to do so.

Adding an IP address recorder is really easy and is a simple modification that amnyone, and I mean ANYONE can make. There is a couple of IP contributions available already, but I thought it would make a decent tutorial for anyone wanting to get a bit “technical” with osCommerce.

The three files that we will be amending are;

  • checkout_process.php
  • admin/orders.php
  • admin/includes/languages/english/orders.php

and we will be amending the orders table in the database to record the IP address.

Step 1: checkout_process.php

This file does the grunt work of recording orders made, so we need to add 1 line of code as so;

Find:
[php]’currency_value’ => $order->info[‘currency_value’]);[/php]

Change to:
[php]’currency_value’ => $order->info[‘currency_value’],
‘ip_address’ => tep_get_ip_address());[/php]

Step 2: admin/orders.php

This files shows the orders made, we need to add a few pieces of code to this file.

Find:
[php]

[/php]

Add this line of code directly underneath it:
[php]

[/php]

Find:
[php]$orders_query_raw = “select o.orders_id …………[/php]

Change to:
[php]$orders_query_raw = “select o.ip_address, o.orders_id ………..[/php]

This is repeated another two times.

Find:
[php]

[/php]

Add this line of code directly underneath it:
[php]

[/php]

Step 3: admin/includes/languages/english/orders.php

Simply add this piece of code:
[php]define(‘TABLE_HEADING_IP_ADDRESS’, ‘IP Address’);[/php]

Step 4: Database changes

Run this SQL file to amend your database to allow it to record the IP address;
[php]ALTER TABLE `orders` ADD `ip_address` VARCHAR( 20 ) NOT NULL;[/php]

That is it. If you have correctly made the changes, the buyers IP address will be recorded and will show in the order summary screen.

Gift Wrapping in osCommerce

Chris writes;

I was thinking that it would be great if you make a constribution that It will add a checkbox on the checkout about a giftwrap. Also under this option it would be good a textbox so the customer can leave a message to be in the card outside of the giftwrap.. you can make the constribution to work with extra cost or free.. At this time there is one too old constribution about giftwrap but it is too bad made..

The old contribution that Chris is referring to is this one – having looked at it, I can see that it’s a real dogs dinner of coding. No wonder there is a need for a new, cleaner version!

My idea would be to create a new, lean and mean order_total module which you can set up in Admin and insert a price (maybe a fixed price or a percent of order sub-total price). Somewhere in the checkout procedure have a checkbox that asks if you would like to “gift wrap” the order which triggers the module. I believe it is pointless to have a comments box attached to this, as there is already a very usable comments box on each checkout page!

Also it is old the constribution I am talking about and it doesn’t work correctly with the languages.. So it would be good if you make a new one for RC2..

With my idea there would be only 1 language file (per language) so it would be easy to set up…

I like the way you make the constributions because you don’t affect to many files from the standard oscommerce files..

Thank you – that’s the whole idea of my contributions – pack as much as possible into the smallest codebase and try not to amend base files very much. As an example, in the existing giftwrap contribution there is a whole class file! What on earth for? Does not make any sense at all.

I believe that with my idea for the codebase, I can make 1 order_total module, it’s language file, and then a couple of small code additions in the checkout pages. Job done – install time on a shop would be a maximum of 5 minutes.

So, this leads me to getting someone to pay for my time to make it. If anyone is interested to do so, I suspect that I can get this coded up for $50 (if you are willing to donate the code back to the osCommerce project) or $100 (if you want the code all to yourself). Should anyone be interested enough, please email me, my email address is up there ^

Donate The Change to Charity – osCommerce

A new contribution which allows your buyer to “round up” his order to the next nearest whole dollar/euro/pound etc. So instead of paying say $96.32, they can “round up” to $97.00 – and you, the shop owner would then do whatever you want (donate to charity I’d assume!) with the extra 0.68.

Only tested on one live shop and on my localhost test shop – but works well. Future updates will include a way to totalise the “round ups” somewhere in the Admin section.

This contribution was sponsored by Furry Family Supplies – thank you very much Lindsay!

At this moment, rounded up figures can be seen on each individual order, as it has been coded as an order_total module.

Installation is easy, download the zip from here to your desktop, unzip it and you will find some txt files and some php files. Upload the php files to the correct places! Any txt files have code which needs to be added to the existing php files of the same name. Once installed, turn it on in your Admin section (order total modules) remembering to give it a unique sorting id.

‘ . tep_image_button(‘button_continue.gif’, IMAGE_BUTTON_CONTINUE) . ‘‘; ?>