Uncategorized (20)


Node.js app framework demo site

I’ve started running a test site for the new framework here

There’s not much there yet, a couple of pages (dynamically loading content from the database, ooooh!) and not much else… but I’ll add more to it as I add features.

It’s currently running on an old laptop in my front room, so don’t expect too much in the way of performance!




Enabling ExpressCache on the Asus UX32A

One of the perks of my job is that I get to work from home and, as a result I managed to talk my boss into forking out for a new laptop for me.  After some consideration I went for the Asus UX32A, which is a halfway house between an ultrabook and a standard laptop.

 It’s much cheaper than an Ultrabook, but Asus have obviously cut some corners to meet that price point.  The screen is a little disappointing, and it only comes with 4GB of RAM (although you can upgrade one of the modules for a total of 6GB).  More importantly though, instead of an SSD Asus have opted for a ‘hybrid’ disk approach with this model.  It has a standard 500GB hard disk, and a 24GB SSD which is used as a cache or buffer between the disk and the rest of the machine.  The theory is that this allows much quicker access to things that you use regularly, while still aloowing the relatively huge storage space of a disk.

The only problem is, this isn’t enabled by default!

I was struggling to find out how to activate this feature on my new machine, but some quick googling led me to realise that I needed to install the ‘ExpressCache’ software from Asus  (it’s actually a piece of software by a 3rd party company, but you need to Asus licensed version to run on the UX32A).  However, here I hit another problem:  the only link I could find to this software was a dead one.

Luckily Asus actually include this software on the hard drive (it’s just not installed, for some reason that I’m sure made sense to somebody) but if you’ve formatted your disk worry not, I’ll include links to the software at the bottom of this post.  Here’s how to install it:

 

1: first off, you need the intel ‘Rapid Storage Technology’ Driver to make Expresscache work.  Helpfully, Asus also include this on the hard disk at:

C:\eSupport\eDriver\Software\Others\Intel\IRST\Vista64_Win7_64_Win8_64_11.5.0.1207

So install that (your computer probably needs a reboot after that install).

 

2: Now install the expresscache software which you can find at:

C:\eSupport\eDriver\Software\Others\other\ExpressCache\Win8_64_1.0.86

run the ‘setup_x64’ executable in that directory.  And then do another reboot when prompted.

 

When your computer restarts you should be running expresscache (yay!).  However, there’s nothing in your start menu (or start screen, whatever) to indicate you’ve installed something new, so how to check that expresscache is installed and working?  Well, for that you need to run a command line program.  Open up an administrator command prompt, navigate to:

C:\Program Files\Diskeeper Corporation\ExpressCache

and run ‘ECCmd.exe -INFO’

you should hopefully see some output like this:

Capture

 

As promised, here’s the files you’ll need:




Pad project day 5: pushing through

Today I finally got my work desktop set up how I want it, so I thought I’d share my experience.  My main desktop PC is a great hulking beast of a machine, that was originally built to play games on.  As such, it uses quite a hefty amount of power to run and sounds not unlike an aircraft taxiing for take-off.  Luckily, I also have a laptop that (amazingly) has dual display outputs on it.  So that’s what I use now.  However, I couldn’t just install windows on it and have done with it… that would be far too simple, no instead I decided to return to my love of Linux.

In the past I’ve tried various flavours of Linux.  I started (as do most people) with Ubuntu which is generally seen as a starter verions of Linux.  It’s easy to set up, but eventually you find yourself chafing at some of the design decisions… and it’s pretty slow compared to other distros.  So after tinkering around with various distrobutions (slackware, gentoo etc) I eventually settled on Arch linux which was fantastic… if you like spending at least 25% of your work time tinkering with your desktop rather than actually working.  Unfortunately, I’ve long since lost my desire to spend hours trying to get various bits of uncooperative software working so for my current day to day work machine I went with something a little more stable…. so, behold my Debian desktop:

Screenshot - 100113 - 21:55:35

 

That’s the ‘Mate‘ desktop environment running with the ‘Gray Revenge‘ theme by the way, which is a lovely blend of simplicity and elegance.  Incidentally, the gnome 3 desktop is just…well, it’s a mess to be frank.  It seems like everyone is trying to invent new desktop paradigms at the moment.  Gnome has it’s Gnome 3 effort, windows 8 introduces the new start screen, Ubuntu has its Unity thing… I really don’t see what’s wrong with the tried and tested desktop paradigm that everyone knows.

For comparison here’s Unity which seems to offer revolutionary new program launchers and docks and…so on and so forth:

 I can understand the concept of trying to push the desktop experience forward but really…at this point, I’ve become so used to working in a certain way that my entire thought process is structured around the way my desktop works.  I shouldn’t have to change my thought process to change to a different desktop environment…and in fact I don’t, because there’s alternatives out there.  For windows there’s freeware available to get your start menu back (and so away with the touch centric start screen) and for linux there’s something like Mate.

Mate is everything a modern desktop environment should be in my opinion, it takes everything that was good about Gnome 3 and continues to add to it with new visuals and so on.  I was originally going to use xfce4, which I’ve tried in the past…and that’s also a really good desktop environment.  However, my main problem with xfce4 is something really trivial but really annoying: the panels are made up from the same widgets used in the rest of the environment.  Since it uses the GTK widget toolkit for everything (including the panels) and the window switcher buttons on the panel are just that (buttons), you can’t get a really good dark theme for xfce4 that doesn’t also completely screw the look of basic window elements.  Most annoying.  I’m sure there’s some way around it, but during my experimentation to try and figure it out I stumbled onto the Mate desktop and stuck with it since it does everything I want.

Most of my work involves PHP in some for or another, so rather than hand editing files in Vim (which is just…well, it’s not my favourite pastime  I use the rather excellent Aptana studio.  It’s basically Eclipse, with a load of php centric plugins offering code completion, hinting and so on.  Other than being slightly more heavyweight than I feel is really necessary, it’s brilliant.  There is a slight tendency to hang occasionally, especially when selecting multiple remote files but its ability to connect to sites via ftp and work on remote files (uploading automatically on save) is a godsend.  Much easier than downloading sites, editing them then re uploading the finished articles. I’ve also recently discovered the joys of using a black on white theme in my ide and have to say, it’s really helped with eye strain and general alertness late in the day.

So, that’s my desktop really.  I use a pair of Benq 24″ monitors which (handily) have selectable inputs on them, one each of DVI, VGA and HDMI…which means I can switch from my main desktiop to my work laptop easily by pushing a couple of buttons and swapping my input devices over.

Hmm,. I think that’s enough rambling for today…I’m really not sure this post a day project is actually accomplishing anything while I’m posting random crap like this.  Maybe posting less frequent, but more informative or useful posts would actually be better for my general productivity.  Hmm, might be time for a rethink.  Although I’m off to my first therapy session tomorrow, so I might actually have something worthwhile to post.




Pad Project Day 4: Random brain dump

Today, let’s talk about some good old random crap.  Here’s what’s on my mind at the moment (excluding stuff that…well, isn’t suitable for a public venue).

1) Facebook.

I disabled my facebook account a couple of days ago as part of my attempt to actually do something productive with my time.  Before that I would spend literally hours each day just sort of…looking at facebook.  Maybe occasionally posting random thoughts onto it but generally just looking at it.  It’s truly insidious how facebook has wormed its way into our lives to the point where it seems to have become a fundamental part of how we interact with each other.  I’m genuinely shocked now if I meet someone and they don’t have a facebook account.  In fact, I’m convinced that the rise of facebook has something to do with the global economic meltdown of the last few years.  I bet if you correlated the rise in facebook users against inflation (or some other measure of economic worth) you’d see some pretty interesting results.  Also (since I just thought of it) guess what the fastest growing economy in the world is?  That’s right, China.  And guess what website (among others) is blocked in China?  Hmm.

2) Pets

I’m currently the nominal owner of 4 animals.  3 cats and a dog.  None of which I wanted in the first place, and everyone one of which gets right on my tits to a greater or lesser extent.  The dog is… reasonable.  Apart from the fact he smells.  A lot.  I don’t know if there’s actually something wrong with him, but a few days after having a bath he…well, he smells like a tramps socks basically.  Not pleasant.  Other than that he’s pretty amenable.  Oh, except when you take him for a walk you have to be constantly vigilant for other dogs.  God forbid another dog should dare to walk within 100 yards of him.  Despite being the size of a handbag, he’ll happily try to fight anything on 4 legs.  Anyway, that’s the dog and like I said I can deal with him.  Other than walking him and feeding him (and shutting him in the kitchen at night so he doesn’t decide to lovingly leave his ‘scent’ all over my carpet) he’s pretty easy going.

The cats though just piss me off to an amazing degree.  To be fair, I’ve never really been a cat person… I’ve always had a very stand offish relationship with them.  Then, a few years ago I was talked into getting a cat due partly to the mouse problem we had in the house we lived in.  That worked brilliantly, the cat we got (a little black thing) was a kick ass hunter and within a couple of weeks we had a mouse free home.  I kind of made my peace with that cat, I’d occasionally play with her and so on…all well and good.  Then my partner decided we needed another cat.  I have no idea why.  He’s the stupidest fucking animal on the planet.  But again, after a number of years I grew…not fond, but tolerating of him.  Yes it pisses me off that I have to get up at least 15 times a day to let them in or out of the house, but I can cope with that.  Anyway, the third cat comes from another failed relationship… he’s currently lodging with me while my ex tries to find somewhere permanent to live.  He’s…fairly docile actually, doesn’t really both me too much.

So…individually we’ve seen that any of those animals is actually not much of a bother.  However, 4 of them in one house is just a 16 legged route to madness.  The original cats don’t get on with either the new cat or the dog.  The dog will eat any cat food that isn’t immediately eaten by the cats.  The new cat hisses at the old cats whenever he see’s them.  One of the original cats will take any opportunity at all to leg it upstairs and go to sleep on my bed (I don’t like cats upstairs, so I try to stop this happening whenever possible).  The only time they’re not pestering to be fed is when they’re outside, and at that point they’re usually pestering to be let in.  Pets man, they’re a complete nightmare.

3) Social anxiety disorder

This is actually preying on my mind quite a bit at the moment.  Ever since I can remember, probably for at lest the last 15 years or so, I’ve had serious issues with social situations.  To the point where I find it incredibly difficult to leave the house some days.  Walking down the street turns into a game of ‘which ridiculous panic attack type symptom will I have today’.  Will it be the legs that suddenly forget how to work?  The sudden intense sweating?  The amazingly embarrasing blushing?  Not fun at all.  A couple of months ago I decided to actually do something abut all this and got in touch with my local NHS service since, as well as making it difficult to actually get out and do stuff, this combined with working from home meant I was actually getting quite depressed and turning into a bit of a recluse.  A depressed, reclusive hermit with 3 cats and a dog.  Not good at all.  Anyway, rather annoyingly since doing the mental health assessment (no, I’m not going to top myself.  Really.)  and finally getting an appointment to see a counsellor I’ve actually found that I’m finding it much easier to go out.  I mean, I still don’t choose to go out if I don’t have to… but on the occasions when I do have to venture into the outside world I’m finding it much easier to cope with.  Which is kind of annoying, because…well, what if the counsellor thinks I’m just making shit up or something?  Or what if I’m somehow cured myself and don’t actually need counselling any more?  Well, my first appointment is the day after tomorrow (ha, that’s the film that’s on telly at the moment) so we shall see how things transpire.

Well I could actually carry on ranting about random stuff, but I think I’ll leave it there for today and actually save some for tomorrow.  So…that’s all folks!




Pad project day 3: on the giving up of things

So…I doubt I’ll make it to 1000 words today, not feeling particularly inspired to write anything.  But I guess that’s the point of this little project so let’s persevere.  Today I’m going to talk about my life goals for 2013, and specifically about the giving up of dependencies.  At the end of 2012 I decided to make some major changes in my life.  I signed up for therapy to treat my long term problems with social anxiety disorder (I’ll probably dedicate a post to this at some point, but not today) quit smoking (more on that later) and also decided to quit coffee to truly make myself independent of any chemical dependencies.  In addition I’m hoping to get some work done on my house in preperation for either selling it in 2014…or more likely continuing to live in the same, but slightly gentrified house.

Quitting smoking was easy.  I’ve tried to quit cold turkey in the past with varying, but inevitably poor results.  I think the longest I’ve ‘quit’ for using the cold turkey method has been about 6 months, but even then it was interspersed with the odd cig here and there.  I mean, if I wasn’t buying them it wasn’t like proper smoking right?  Eventually I’d have some major life crisis that I’d use as an excuse to start again… an argument with my girlfriend, or a particularly bad day at work.  It was irrelevant what the trigger was really, the end result was always the same.  That one packet I bought to see me through the rough spot turned into 2 packs, then 3…then well  I might as well smoke til the end of the week right?  And at some point I just gave up and started smoking again.  At one point I even tried Alan Carr’s stop smoking book.  Not the camp alleged ‘funny man’ off of the telly, but the self help guru who’s ‘Easy way to quit smoking’ has “helped millions of people become happy non smokers”.  Apparently.  I think the key word there is ‘happy’.  Whenever I’ve quit smoking in the past I’d always felt like a smoker who just wasn’t smoking at the moment.  I may not have constantly craved cigs, but the longing was always there in the back of my mind, waiting to resurface.  Until I got rid of that longing, I think I always knew I’d never be a non smoker… happy or otherwise.

For this attempt to quit I decided to stop messing around and see what the NHS offered.  It turns out they’ve got quite a good service dedicated to helping you quit.  After getting in touch with the service I was given an appointment with my local stop smoking counsellor (a lovely lady named Sue) who talked me through the types of Nicotine replacement therapy that are available and offered advice on which ones would be best for me.  To be honest, I’d already decided to go with patches and that’s what I ended up with.  I also walked out with some inhalators… which are sort of like the e-cigs that are booming in popularity at the moment, but a bit crap.  I haven’t really used the inhalator much at all, despite being told I can use up to 6 capsules a day, I rarely get through one a week.  They are nice for those moments when the habit kicks in (after meals etc) but with me smoking was never really about the habit, it was purely about the addiction.  I never even really liked smoking, it made me feel sick and lethargic.  Anyway, after 8 weeks on the patches I can honestly say I’ve lost the urge to smoke.  I’m on stage 2 of the patches, which is step down in dosage from step one… but sometimes I’ll go a whole day without realising I haven’t put a patch on, which bodes well for being able to stay off the cigs once I finish my patches.

So that’s smoking knocked on the head, time to tackle my other big addiction: caffeine   Since I started working from home, I’ve been averaging a cup of coffee every hour or so… which doesn’t sound like a lot, but I guess it soon adds up.  I’ve not been sleeping particularly well at night (those cups of coffee in the late afternoon do tend to linger) and generally feeling pretty rough when I wasn’t on a caffeine high…so the time has come to do something about it.  This weekend I made the leap (prompted by the fact I ran out of coffee) and spent most of it feeling pretty bad.  On saturday (my first full day without any coffee) I had a pounding headache most of the day, and felt really nauseas, however on Sunday most of that had passed and on monday my caffeine replacement therapy arrived (courtesy of Twinings teas):

 

2013-01-08 22.47.48

 

On the left there is my early morning pick-me-up of ‘lemon and ginger’ which…does the job pretty well actually.  Unfortunately it also tends to upset my stomach (seriously, I have the digestive system of a small child) which is where the one on the right comes in.  The Nettle and peppermint is a really soothing blend, that does actually make me feel more relaxed and definitely helps settle my stomach.  Before those 2 arrived I was finding caffeine much harder to quit than nicotine.  I’d crave cups of coffee 4 or 5 times a day and be constantly feeling ill.  Now however I think I’ve turned a corner.  Whether it’s just a placebo effect or the teas are actually helping is hard to say….but whatever they’re doing it works.

Hmm, still 70 words left to the target so I guess I can mention the other thing I want to get sorted this year…I want to at least try archery.  It’s been a long time aim (ha, archery pun) of mine to give it a go, and this is the year it’s finally going to happen.  There’s an Archery club just down the road in Bolton that does beginner courses, so as soon as they start up again (I missed the last one at the end of last year) I’m determined to get down there and give it a go.  As well as being something I’ve wanted to try for literally years, it should be a good way to get out of the house and meet people (neatly tying in with the social anxiety thing) and I think it’s generally good for me to have a hobby that doesn’t involve computers for once.

 




Magento: Block users using a group

One of the most glaring omissions of magento is a way of blocking users. Currently your only option when faced with a user you wish to ban from the site is to do some kind of IP blocking in your web server configuration, or delete the user account. Neither of those options is really useful, IP blocks are difficult to maintain and if you delete a user account there’s nothing to stop the miscreant just creating a new account.

Here’s how you can create a simple module that allows you to set up a ‘blocked’ group. When customers are placed in this group they can still log in, however they’re not able to add anything to their cart and thus can’t actually place an order.

First up we need to create our module folder structure. Here I’m using a namespace of ‘Tallpaul’ and a module name of ‘bangroup’, but you can change these according to your requirements (just make sure you change them throughout, or you’ll get missing classpaths and all sorts of fun).

 

 

 

 

 

 

You can see we only have a couple of files in here.  ‘Config.xml’ is a configuration file that defines how our module is going to behave, and’CartController.php’ is our code that’s going to stop blocked users from adding items to their cart.

Lets take a look at ‘config.xml’ first.

<config>
 <modules>
 <Tallpaul_Bangroup>
 <version>0.1.0</version>
 </Tallpaul_Bangroup>
 </modules>
 <frontend>
 <routers>
 <checkout>
 <args>
 <modules>
 <tallpaul_bangroup before="Mage_Checkout_CartController">Tallpaul_Bangroup_Frontend_Checkout</tallpaul_bangroup>
 </modules>
 </args>
 </checkout>
 </routers>
 </frontend>
</config>

After the usual configuration stuff of defining a version for our module, there’s only one line here that does anything.  We’re defining that our module (tallpaul_bangroup) is overriding a specific controller (Mage_Checkout_CartController) with a new controller (Tallpaul_Bangroup_Frontend_Checkout).  And that’s pretty much it.  You can see here that controller overrides are dfined in a different way to bloc / helper / etc overrides.  I’m not entirely sure why, but this is just the way magento does it.  It usually takes me a bit of trial and error to work out how to override a specific controller, but once you’ve done it a few times it becomes second nature to map these files to a classpath.

Anyway, now we’ve got our configuration out of the way, lets have a look at CartController.php.  In here we’re going to extend the magento checkout controller class, and override a couple of functions.

/**
 * Shopping cart controller
 */
require_once Mage::getModuleDir('controllers', 'Mage_Checkout').DS.'CartController.php';

class Tallpaul_Bangroup_Frontend_Checkout_CartController extends Mage_Checkout_CartController
{

  /**
   * Check if user is blocked (ie: if they're in the 'Blocked' group)
   */
  public function isBlocked(){
  		if(Mage::getSingleton('customer/session')->isLoggedIn())
		{
  			$groupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
			$group = Mage::getModel('customer/group')->load($groupId);
			$groupName = $group->getCode();
			if ($groupName == "Blocked"){
				return true;
			}
		}
		return false; //user can't be blocked if they're not logged in
  }

  /**
   * Empty current user cart
   */
  public function emptyCart(){
  		$cartHelper = Mage::helper('checkout/cart');
     	$items = $cartHelper->getCart()->getItems();
        foreach ($items as $item) {
            	$itemId = $item->getItemId();
            	$cartHelper->getCart()->removeItem($itemId)->save();
        }
  }

   /**
     * Shopping cart display action
     */
   public function indexAction()
   {
   		if ($this->isBlocked()){
   			$this->emptyCart();
		}
		parent::indexAction();
   }

    /**
     * Add product to shopping cart action
     */
    public function addAction()
    {
			if ($this->isBlocked()){
				$this->emptyCart();
				$this->_goBack();
                return;
			}
		parent::addAction();

    }

}

 

The actions we’re overriding are ‘indexAction’ (which is used to display a user’s cart) and ‘addAction’ (called whenever an item is added to the cart.  The other 2 functions here ‘isBlocked’ and ’emptyCart’ are simple helper functions I’ve defined to keep things tidy.

The basic logic here is that when a user adds an item to their cart we first check if they’re in a specific group (here I’ve used ‘Blocked’ as the name of the group, but you can call it something else as long as you update the code in ‘isBlocked’).  If they are we empty their cart, and then return.  The effect of this is to take the user to an empty cart with nothing added to it and no error message to indicate what the problem might be.

As a doublecheck against a user who already has items in their cart when they’re placed in the ‘Blocked’ group, we also add a check to the ‘indexAction’ to empty their cart when they view it.

At the end of our indexAction and addAction we use the nifty trick of calling the relevant method in the ‘parent’ class.  This means our code remains clean and simple, while allowing requests that we don’t want to block using our code to ‘fall through’ to the parent implementation and be dealt with by the standard Magento logic.

Now all that’s required is an ‘activation’ xml file in app/code/etc and we’re good to go.  Create a group called ‘Blocked’, add your rogue users to it and laugh as you imagine their confusion at being unable to add items to their basket.

You can download the code for this article here:

 




Create a bootable USB Drive in windows

This is more of a memo for me than a post for the rest of you, but might be useful if you want to create a bootable USB disk from a windows box (for an example, I used it to create a windows 8 installation drive)

 

Information taken verbatim from this post on the microsoft answers site

1. Plug in a USB device that is 4GB or bigger.
2. Find the disk number of the USB device:
    Open up an elevated command shell, run diskpart.exe.
    Within diskpart, run 'list disk'. The output will list all disks on the computer.
    From looking at the size, infer which one is your USB disk and note down the 
    disk number.
3. Correctly format the USB device:
    Run diskpart.exe and enter the below commands one by one.
        select disk <disknumber of your USB disk>
        clean
        create partition primary
        format fs=ntfs quick label=Win764
        active
        assign letter=Q
        exit
    Now you should see a "Q:" drive in Windows Explorer. This is your USB disk.
4. Mount the 64-bit Win7 ISO:
        Windows does not have a built-in ISO mount feature. So you will have 
        to use a third-party tool. I suggest "Virtual CloneDrive". Once you have 
        downloaded and installed Virtual Clonedrive, navigate to the folder that 
        your ISO file is in, in Windows Explorer. Right-click on the ISO file and 
        select "Mount". After this, all your ISO files should show up in a drive 
        called "I:".
5. Populate the USB disk:
    Copy all files and folders from I: to Q:.
6. UnMount the ISO:
    In Explorer, navigate to the folder that has the ISO, right-click and select UnMount.
7. Boot from USB:
    Turn off the target computer, plug in the USB device, turn on the computer, 
    get to the BIOS boot options (using F9 or some other key, depends on your computer), 
    select USB boot, and you should see setup run.



Magento: Round up currency conversions

Just a quick and dirty (no, not that kind of dirty) tutorial today. One of the websites I work on had the requirement to make its prices look ‘nicer’ when converted to another currency. Currently (little currency pun for you there) the prices look fine in the default currency, which is good old pound sterling like so: £8.00 but when a customer selects one of the other available currencies they see something like $17.34. So, how to make the prices look nice no matter what the currency?

A good, but time consuming way of fixing this problem would be to enter fixed prices for each product in every currency, but who wants to go to that amount of effort? A much easier way would be to round up whenever a currecny conversion is done. Luckily, thanks to Magento’s excellent extensibility this is actually incredibly simple.

First we track down the class which magento uses to deal with currency conversions. A quick google search reveals that the class we want is a Model found in:

/app/code/core/Mage/Directory/Model/Currency.php

And the class name is: Mage_Directory_Model_Currency

Helpfully, we only need to override one method in this class, the aptly named ‘convert’ which looks like this:

 

/**
 * Convert price to currency format
 *
 * @param double $price
 * @param string $toCurrency
 * @return double
 */
 public function convert($price, $toCurrency=null)
 {
     if (is_null($toCurrency)) {
       return $price;
     }
    elseif ($rate = $this->getRate($toCurrency)) {
       return $price*$rate;
    }
    throw new Exception(Mage::helper('directory')->__('Undefined rate from "%s-%s".', $this->getCode(), $toCurrency->getCode()));
 }

The actual code change we need to make here is trivial, all we need to do is change this:

return $price* $rate;

to this:

return ceil($price*$rate);

And since the actual code is so simple, I thought I’d use the rest of this post to go over the various methods of overriding classes like this in magento, and the pros & cons of each.  For standard magento classes like this one, we basically have three ways of making changes to theirfunctionality.  I’ll discuss these in ascending order of… ‘goodness’ (for want of a better term) so if you just want to know the best way, skip to the end.

First up, we have editing the original source file.  This will live somewhere under /app/code/core (in our case it’s /app/code/core/Mage/Directory/) and editing files in here is a bad idea.  Any changes you make will be lost if you upgrade magento, and if you change something and break it you have to deal with restoring backed up files and that can get really messy.

Option 2 is to copy the directory structure of /core into /local (or /community, the effect is the same).  Magento’s auto class loader has a stictly defined way of ‘looking’ for files containing the class it’s currently loading.  Anything in ‘community’ will override the same file in ‘core’ and anything in ‘local’ will override the other 2.  So, if we create a copy of /app/code/core/Mage/Directory/Currency.php in /ap/code/local/Mage/Currency.php and make our changes in there, our changed file will have priority over the original and override it.  The downside to this approach is that it’s not particularly portable or elegant.  You have to copy the entire original file to make one simple change, and you have to replicate the folder structure under /core to make it work… which isn’t particularly nice.

Luckily, Magento offers us a third option (although really, this should always be option 1) and that’s to make use of Magento’s ‘rewrite’ functionality.  Using this, we can override a specific method within a Magento class, we can namespace our files so they stay separated from Magento and other third party add-ons and it’s generally speaking a much cleaner and more elegant solution.  In this example my namespace is going to be ‘Tallpaul’ and my modulename is ‘Rounding’.  Be careful when choosing a namespace and make note of case sensitivity.  I like to keep my namespaces all lowercase apart from the initial letter, and this works well but I’ve had problems in the past with camel cased namespaces (for example TallPaul)…magento is very sensitive about case.

So first we need to create our class, this goes in: /app/code/local/Tallpaul/Rounding/Model/Currency.php

and it looks like this:

class Tallpaul_Rounding_Model_Currency extends Mage_Directory_Model_Currency{
 /**
 * Convert price to currency format
 *
 * @param   double $price
 * @param   string $toCurrency
 * @return  double
 */
 public function convert($price, $toCurrency=null)
 {
    if (is_null($toCurrency)) {
      return $price;
    }
    elseif ($rate = $this->getRate($toCurrency)) {
       return ceil($price*$rate);
    }
    throw new Exception(Mage::helper('directory')->__('Undefined rate from "%s-%s".', $this->getCode(), $toCurrency->getCode()));
 }
}

No surprises here, we’re extending from the original magento class we want to add functionality to. Notice how the only method we declare here is the one we want to override.  Any other methods are handled by the original class, so we don’t need to worry about them.

Now, lets tell Magento that we want our class to ‘rewrite’ the magento class.  We do this with this file:/app/code/local/Tallpaul/Rounding/etc/config.xml

And that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
 <config>
   <modules>
     <Tallpaul_Rounding>
       <version>0.1.0</version>
     </Tallpaul_Rounding>
   </modules>
 <global>
   <models>
     <directory>
       <rewrite>
         <currency>Tallpaul_Rounding_Model_Currency</currency>
       </rewrite>
     </directory>
   </models>
 </global>
 </config>

Here we declare our module and tell magento what version it is, then under the ‘global’ tag we define our rewrite.  In this case we want to rewrite a ‘Model’ so we use the models tag, and the model we want to rewrite is one under the ‘directory’ module.  Specifically it’s the ‘currency’model.  On the file system this corresponds to our original magento class file /app/code/core/directory/model/currency.php.  The mapping between the xml here and the classpath is a little difficult to wrap your head around, but once you’ve worked with Magento a while it suddenly clicks into place and you can easily work out where something lives based on its xml ‘description’.

Now we’ve told Magento what our module does, we need to ‘register’ it with magento and activate it.  As with all modules we do this by adding an xml file to /app/code/etc/.  By convention this should be named ‘namespace_modulename’, which gives us a filename of: /app/code/etc/Tallpaul_rounding.xml and this file looks like this:

<?xml version="1.0"?>
   <config>
     <modules>
       <Tallpaul_Rounding>
         <active>true</active>
         <codePool>local</codePool>
         <depends>
           <Mage_Directory/>
         </depends>
       </Tallpaul_Rounding>
     </modules>
   </config>

A couple of things to note in this file:  First up the ‘codePool’ tag.  This corresponds to the directory under ‘code’ that our modules lives in (so local, community or core).  Also, I’ve added a dependency to ‘Mage_directory’, ie: the module we’re adding functionality to.  This is just to make sure that core module is definitely loaded before we try to add our functionality.   Also worth noting is that you can have as many modules as you want in this activation file by adding more tags under the ‘modules’ tag.  By convention, activation files which contain multiple modules are usually used to activate all the modules in a single namespace and are named ‘Namespace_All.xml.

Anyway, with our activation file in place the module should now work as expected.

Because this is such a simple and trivial mod to produce, I don’t think I need to add downloadable source to this article…however, if you really are that lazy let me know in the comments and I’ll get it uploaded 😀

 




Magento show remote IP in cloudflare: the right way

After writing this post on how to override Magento’s HTTP helper to pull in the ‘real’ remote ip address when behind a reverse proxy system like Cloudflare.  After reading this, Jack at firstvapor.com helpfully wrote in to point out the right way of doing this.

If you look in /app/etc/local.xml.additional there’s some extra nodes in there that you can copy into your local.xml to add additonal funcitonality… and one of the things you can do is add remote headers for reverse proxies.

so, copy the following code into your local.xml under the ‘global’ node:

<remote_addr_headers><!-- list headers that contain real client IP if webserver is behind a reverse proxy -->
           <header1>HTTP_CF_CONNECTING_IP</header1>
</remote_addr_headers>

And that should do the trick!  I’ll leave the other article up as it’s a good tutorial for overriding a helper anyway, but this method is much simpler.




test post

this is a test post!