Jump to content

Archived

This topic is now archived and is closed to further replies.

burt

Postcode Formatting

Recommended Posts

I was asked by someone to code up a system that ensures a UK postcode goes into the DB perfectly formatted - the task was not to ensure that the postcode actually exists, simply to write it into the DB in a particular format:

 

1 or 2 letters 

followed by

1 or 2 numbers

followed by a space

followed by 1 number

followed by 2 letters

and all in Uppercase.

 

Examples (of correctly formatted postcode):

 

AB1 2CD

MN23 4NW

E2 1TG

 

Here is the Problem (incorrectly formatted postcode):

 

mn234nw

Mn234NW

MN2 34NW

mn2 3 4nw

 

All of the above should be properly written as MN23 4NW

 

So, here is your task, come up with a way to ensure that when a person creates an account, the postcode always enters the database in perfect format.  How would you do it ?  There is no particular right or wrong way - though we should try hard to change as little core-code as possible...

 

Have fun ;)

 

Edit:  

Yes, I have a made solution already.  

Yes, this will be shared at the conclusion of the thread.


Help shape the future of Phoenix; join the Phoenix Club

Share this post


Link to post
Share on other sites

There are a lot of regex form validator solutions but well know that you dont like .js do you? :)

 

html5 can do it http://html5pattern.com/Postal_Codes


:blink:
osCommerce based shop owner with minimal design and focused on background works. When the less is more.
Email managment with tracking pixel, package managment for shipping, stock management, warehouse managment with bar code reader, parcel shops management on 3000 pickup points without local store.

Share this post


Link to post
Share on other sites

I probably spent more time messing with this than I should have, because I was looking at validation regex's.  Anyway, based on your criteria this works.  The first 3 lines test it with the first line one of your samples.  Seems like stripping spaces is the best way to start and then put it back.  I made one for US phone numbers a while back because it drove me nuts they way people enter phone numbers.  I also use "ucwords" for names.

<?php
$postcode = "mn2 3 4nw";
$formatted_post = format_postcode($postcode);
echo $postcode . " <br>was entered and formatted to<br> " . $formatted_post;

function tep_format_uk_postcode($postcode) {
  $postcode = strtoupper(str_replace(' ', '', $postcode));
  $suffix = substr($postcode, -3);
  $prefix = str_replace($suffix, '', $postcode);
  $formatted = $prefix . ' ' . $suffix;
  return $formatted;
}

I'm not really a dog.

Share this post


Link to post
Share on other sites

I probably spent more time messing with this than I should have

Exactly what I like to hear :)

 

If I got you thinking about it, no doubt others are too ... we shall see how many ways we can skin this particular cat.


Help shape the future of Phoenix; join the Phoenix Club

Share this post


Link to post
Share on other sites

There are a lot of regex form validator solutions but well know that you dont like .js do you? :)

 

html5 can do it http://html5pattern.com/Postal_Codes

Is client side (eg .js or html5) the correct approach ?

You would need to know which Regex to use, no ?


Help shape the future of Phoenix; join the Phoenix Club

Share this post


Link to post
Share on other sites

Some cases yes it can do, but on global shops never. You are right. Rather concentrate the regexp examples than client side validation. Postal code validation sticks to countries.

Address format or the countries table are the correct place for regexp. ;)


:blink:
osCommerce based shop owner with minimal design and focused on background works. When the less is more.
Email managment with tracking pixel, package managment for shipping, stock management, warehouse managment with bar code reader, parcel shops management on 3000 pickup points without local store.

Share this post


Link to post
Share on other sites

For anyone who wants a go, remember that this little task is only about UK postcode formatting ...

 

1 or 2 letters

followed by

1 or 2 numbers

followed by a space

followed by 1 number

followed by 2 letters

and all in Uppercase.

 

Regardless of what is input into the postcode box.


Help shape the future of Phoenix; join the Phoenix Club

Share this post


Link to post
Share on other sites

Even if you do use a validation regex, it can validate but still be wrong.  However, Fedex will show an address/zip code missmatch and suggest the correction. 


I'm not really a dog.

Share this post


Link to post
Share on other sites

I think you should split the form's inputs:

 

1 or 2 letters [input1]
followed by
1 or 2 numbers [input 2]
followed by a space [nothingneed for that]
followed by 1 number [ input 3]
followed by 2 letters [input 4]
and all in Uppercase [strupper]

 

Combine the inputs ... Done!

 

Alternatively you could use a 3th party geolocation service.

Share this post


Link to post
Share on other sites

Splitting the form will confuse some customers entering data.  People get confused by everything.  I personally don't like it when a phone number entry is split, versus one entry.

 

The way I did it will work without having to split the form.  I looked at several regex and there are some more restrictive than what Burt suggested, but he stated that it did not need to be validated , just formatted. 

 

Because of Burt's examples of incorrectly entered postcodes I

  • stripped the whitespaces and uppercased,
  • captured the last 3 as suffix leaving the remainder as prefix. 
  • Then, just combine them with a space in the middle.

 

On a side note, I did see a post on a forum where someone could not sign up because their UK postcode was incorrect.  They couldn't figure it out for a while but they were enteting it lower case and it was failing.


I'm not really a dog.

Share this post


Link to post
Share on other sites

I would do it with php to give more control. Like

 

arry = str_split(postcode)

 

suffix_end = arry(last three places)

 

! is number (suffix[0] || ! isalpha(suffix[1] || ! isalpha(suffix[2])

 exit - incorrect entry.

 

for ($I < count(arry) - 3))

 if (not space)

 prefix .= arry($I)

 

postcode = prefix . ' ' . suffix

Share this post


Link to post
Share on other sites

I'm all in favour of the regex solution linked to above.

 

regex allows you to do frontent HTML5 validation and backend from the same regex source field (if stored in the country table)


KEEP CALM AND CARRY ON

I do not use the responsive bootstrap version since i coded my responsive version earlier, but i have bought every 28d of code package to support burts effort and keep this forum alive (albeit more like on life support).

So if you are still here ? What are you waiting for ?!

 

Find the most frequent unique errors to fix:

grep "PHP" php_error_log.txt | sed "s/^.* PHP/PHP/g" |grep "line" |sort | uniq -c | sort -r > counterrors.txt

Share this post


Link to post
Share on other sites

Thanks for input to those who posted, I believe @@John W and @@Jack_mcs have a more correct approach - the place for this type of one-off checking is best done server side...

 

Hopefully also got some of you thinking about "code", even if you did not post. And I know I got others thinking much deeper than my initial project/question; @@bruyndoncx @@wHiTeHaT @@Gergely

 

 

To bring this to a conclusion, here is what I did (which is neither right nor wrong, just a way to do it);

 

1. create_account.php

 

Find:

 

$postcode = tep_db_prepare_input($HTTP_POST_VARS['postcode']);
Add After:

 

$postcode = $OSCOM_Hooks->call('createaccount', 'FormatPostcode');
2. hook file:

 

$postcode = strtoupper(preg_replace('/\s+/', '', $_POST['postcode']));
return tep_db_prepare_input(preg_replace('/([[:digit:]][[:alpha:]])/', ' \\1', $postcode));
Functionality does this:

 

Line 1:

a/ take the _POST'd data from the postcode input box

b/ strips out all whitespace

Line 2:

c/ looks for the first occurrence of a digit followed by a alpha character

d/ adds a space before it

c/ makes it safe for DB input

 

And that is how I did it, a grand total of 1 extra line of code in create_account.

 

The best thing about using the Hook system is that you can see all the hooks in use on an admin page, which means that if/when you upgrade to a newer version of osc, you can easily see what is active and transfer them to the new software. Hooks are set to be quite an important part of the upcoming osCommerce releases.


Help shape the future of Phoenix; join the Phoenix Club

Share this post


Link to post
Share on other sites

@@burt You need to add error checking. What happens if someone types in MN23 N4W?

Share this post


Link to post
Share on other sites

@@burt You need to add error checking. What happens if someone types in MN23 N4W?

That would require some extra lines of code in the hooked file, using the .gov [ https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/413338/Bulk_Data_Transfer_-_additional_validation_valid_from_March_2015.pdf ] regex;

 

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))
[0-9][A-Za-z]{2})$
If the inserted postcode does not comply with that Regex, direct back to the create_account page asking the user to fix it, but you would then also need to know their country (that Regex obv only works with UK postcodes). Grab the _POST[country], get the Regex from the DB.

 

In this case, we go back to client side and ask them for their country first (which I personally *hate* to see on sign up forms, country first), then update the regex using .js trickery...but that was not a part of this project :o

 

Then you also need a way to add Regex's to the country table => admin change.

 

As we can see, once we get into a project, it is hard to simply stop at what the client asks for (and has budget for) ...


Help shape the future of Phoenix; join the Phoenix Club

Share this post


Link to post
Share on other sites

@@burt

Whilst I do not have a clue what a regex is or anything like that, I do appreciate that you are in the mind frame of keeping things simple. How you can reduce pages of some code to just a few lines, I will never know. Keep it Simple. Thank you.


REMEMBER BACKUP, BACKUP AND BACKUP

Get the latest Responsive osCommerce CE (community edition) here

It's very easy to over complicate what are simple things in life

Share this post


Link to post
Share on other sites

Is the hooks file OSC - BS specific?

 

Many Thanks


Now running on a fully modded, Mobile Friendly 2.3.4 Store with the Excellent MTS installed - See my profile for the mods installed ..... So much thanks for all the help given along the way by forum members.

Share this post


Link to post
Share on other sites

Thanks @@burt I cant find a hooks file in my 2.3.4 install....

 

Would the above solution work where the account is created by a customer using paypal express to pre-populate the fields wnen they checkout using PPE?

 

thanks


Now running on a fully modded, Mobile Friendly 2.3.4 Store with the Excellent MTS installed - See my profile for the mods installed ..... So much thanks for all the help given along the way by forum members.

Share this post


Link to post
Share on other sites

@@burt I dont want to lose these from backside I have collected some regular pattern for another countries. I hope its usefull so I post here

$ZIPREG=array(
	"US"=>"^\d{5}([\-]?\d{4})?$",
	"UK"=>"^(GIR|[A-Z]\d[A-Z\d]??|[A-Z]{2}\d[A-Z\d]??)[ ]??(\d[A-Z]{2})$",
	"DE"=>"\b((?:0[1-46-9]\d{3})|(?:[1-357-9]\d{4})|(?:[4][0-24-9]\d{3})|(?:[6][013-9]\d{3}))\b",
	"CA"=>"^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])\ {0,1}(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$",
	"FR"=>"^(F-)?((2[A|B])|[0-9]{2})[0-9]{3}$",
	"IT"=>"^(V-|I-)?[0-9]{5}$",
	"AU"=>"^(0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2})$",
	"NL"=>"^[1-9][0-9]{3}\s?([a-zA-Z]{2})?$",
	"ES"=>"^([1-9]{2}|[0-9][1-9]|[1-9][0-9])[0-9]{3}$",
	"DK"=>"^([D-d][K-k])?( |-)?[1-9]{1}[0-9]{3}$",
	"SE"=>"^(s-|S-){0,1}[0-9]{3}\s?[0-9]{2}$",
	"BE"=>"^[1-9]{1}[0-9]{3}$",
  "HU"=>"^[1-9]{1}[0-9]{3}$"
);

Your UK is better I think.

The hook system could be very simple and dont have to connect countries table just run only if POST country value is found.


:blink:
osCommerce based shop owner with minimal design and focused on background works. When the less is more.
Email managment with tracking pixel, package managment for shipping, stock management, warehouse managment with bar code reader, parcel shops management on 3000 pickup points without local store.

Share this post


Link to post
Share on other sites

There are two cases in my mind

1. never disturb registration but analyse postcode on administration

2. force the postcode immediately with feedback forms and .js

 

In first case admin can use a repair tool for it on backside with php http://php.net/manual/en/function.sprintf.phpstring formatter scripts.
Its an alternative idea..


:blink:
osCommerce based shop owner with minimal design and focused on background works. When the less is more.
Email managment with tracking pixel, package managment for shipping, stock management, warehouse managment with bar code reader, parcel shops management on 3000 pickup points without local store.

Share this post


Link to post
Share on other sites

has the london post code format been considered here?

 

eg

AANA NAA  - EC1A 1BB

 

wouldnt that need a little more code


osC CE live - developing osC Phoenix adding modules with no core changes(awesome and easy!)

Share this post


Link to post
Share on other sites

has the london post code format been considered here?

 

eg

AANA NAA  - EC1A 1BB

 

wouldnt that need a little more code

 

 

Hmmm.  My original regex would format that as so:  EC 1A 1BB

in other word an extra space in between C and 1.  Not good.

Bloody Londoners ;)

 

Changing the regex to:

 

 

return tep_db_prepare_input(preg_replace('/([[:digit:]][[:alpha:]][[:alpha:]])/', ' \\1', $postcode));

 

and it now looks for a digit followed by two alpha's which can only occur in 1 place...which works well for all postcodes I have tested it against.

 

Thanks for the heads up on those London postcodes @@Mikepo


Help shape the future of Phoenix; join the Phoenix Club

Share this post


Link to post
Share on other sites

Now that the postcode is sorted, something should be done to capitalise names and addresses, as I spend hours correcting these every day, especially those that sign up with a mobile. They just do not like using capital letters.

 

Sorry to do off topic. Just a pet hate of mine.


REMEMBER BACKUP, BACKUP AND BACKUP

Get the latest Responsive osCommerce CE (community edition) here

It's very easy to over complicate what are simple things in life

Share this post


Link to post
Share on other sites

×