Follow me: @D_mitar

Most read posts recently



Jul 19th 2010 × summer outdoor sandals blues

This is nothing to do with javascript but I am on a holiday, after all…

Bit gutted to find that my otherwise excellent Newport Sandals by Keen have started to pack it in after 2 seasons of tear and wear – it seems they were not as water resistant as I was initially led to believe. Nasty side effect – the leather now stinks so bad (due to getting wet a few times) I cannot wear them inside my car. Such a shame, I really really really liked them…

keen newport sandals

What to buy now or do I just order another pair? Hrm…


Nov 4th 2009 × CubeCart 4 security vulnerability: is your store at risk?

Whilst reading on XSS attacks today, I found this recently reported exploit in CubeCart 4 that can gain an attacker full administrative access to the store.

Not only that, it can help them dump your entire store DB – products, cats, users, orders, the works. Anyway, you get the idea. “CubeCart responded and informed their customers about this vulnerability” – as technical advisor for a site that runs on CC4, I can testify to the fact that the site owners were not informed of any such. Nice.


Aug 3rd 2009 × Enough of the jQuery already…

This is not much of a post but a bit of a rant. “It’s my party and I’ll cry if I want to”, right?

I have a problem with jQuery–not with the framework as such, but with some of its users. And who in their right mind wouldn’t be getting the amp when just about any webdev site, forum and topic is now full of clever know-it-alls that come and declare how ‘such and such jQuery plugin will do what you want’. There’s always a jQuery plugin for everything, didn’t you know…

Does not matter if the question at hand is on vanilla javascript or mootools, just add jQuery and whistle… Already use another framework? Get jQuery anyway, it’s so good you can run in compatibility mode!

The sad part is in how a large portion of these jquerysts have absolutely no understanding of vanilla javascript. It feels as if some of them inadvertently consider ‘javascript’ and ‘jQuery’ to be synonymous…

Aren”t people just getting carried away slightly? I’ll be the first to admit how jQuery is full of awesome features, documentation and support. Why, it’s so great and so far removed from standard javascript syntax that some go to extreme lengths to mimic its shorthand in other frameworks as well. Just the other, having downvoted a jQuery solution for a mootools question on stackoverflow, I was told how $(“someid”).click(); was a perfectly reasonable and valid mootools syntax (as shown by David Walsh)

Paradoxically, in lowering the standards and requirements (in the sense of, by being too accessible and too easy to use), jQuery has spawned an army of coders that don’t even have to learn javascript. A lot of badly formed code gets released, complete with a disregard for best practices, memory, bandwith use, usability and god knows what else…

Still, perhaps there will come a day when mootools sports a high-spirited in-your-face following. For we have a lot to be tooting about, after all…


Jun 9th 2009 × CubeCart problems: no shopping bakset and login functionality for some users

There’s yet another one of these problems that are inherently weaved deep into CubeCart that you just wouldn’t know about… It displays different versions of pages to search engines and to humans, namely–it disables the shopping basket and checkout functionality as well as the login and registration.

First of all, needs to be said that troubleshooting this and finding the reason for users being unable to purchase off a CubeCart site is an absolute nightmare. When a customer says they use ‘bog standard’ IE8 and report their ‘add to basket’ button doing nothing whatsoever, one tends to think ‘has the javascript handler gone wrong?’. You go on a wild goose chase, trying to reproduce the problem and failing despite of installing various javascript exception tracking modules, looking through logs and quizzing puzzled shoppers. All the while, you can’t help but wonder about the possible extent of the problem, how many users get this? And then – you catch a break by accidentally discovering customers unable to purchase also lack the login/register links – time to start connecting the dots…

From session.inc.php, which controls the login / register links in CubeCart:
if (!$cc_session->user_is_search_engine() || $config['sef'] == false)

The template does not get shown to search engines? That makes sense… having different versions of pages shown to users and to spiders is not only a bad practice (google really don’t appreciate “cloaking” techniques), there is just NO need for it whatsoever. In order to prevent spiders from indexing pages that are deemed irrelevant to e-commerce and spill page rank / relevance, they could have been disallowed from within the robots.txt file. A rel=”nofollow” could have been applied to links to such pages… but what have the clever folks at CubeCart done instead?

They created a boolean method into the sessions class that decides if the user is a bot or not, user_is_search_engine(). It does so by comparing the contents of a file called spiders.txt, filled with “known” extracts from the user agent strings of various spiders from around the web, against the user agent string of the visitor. To be fair, the original idea for this kind of testing comes from OS Commerce…

The problem is when a legitimate customer is being discarded from using the site’s e-commerce because their user agent string is customised in a ‘bad’ way. How does that work? The original CubeCart spiders.txt file has lines that reject things like:

‘googlebot’ but also just ‘google’,
‘msnbot’ but also just ‘msn’

And so forth… multiply by x number of toolbars and custom strings CubeCart may never know about and you have a HUGE problem. For instance, users with Google Desktop get their user agent string set to Mozilla/5.0 (compatible; Google Desktop) so they promptly get rejected. Luckily, that’s not a very popular application but the “MSN” string and the absolutely COUNTLESS numbers of people that have got a user agent string like this one: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; Sky Broadband; GTB6; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; InfoPath.2; .NET CLR 3.5.21022; MSN OptimizedIE8;ENGB) presents a VERY real problem. MSN optimized IE8? Not on my shop site, mate.
edit: check your spiders.txt version, if it predates august 2008, you are affected.

I have been looking at the user sessions table and have thus far found over 3000 genuine users that have been rejected by CubeCart’s loose user agent matching routine. That’s a lot of business to lose and the store owners are understandably upset. It’s not free software and at a testing time like the credit crunch we’re enjoying, having your own store work against you is far from ideal. The real frustration comes from the fact that people had reported an intermittent loss of shopping cart functionality on the CubeCart forums and on their bug / ticketing system. Reported and dismissed – apparently, too difficult to trace or unsupported due to store being customised. Every programmer makes mistakes, but being unable to rectify them and failing to provide support to your paying customers – it’s just bad business. I am sorry to say, CubeCart has failed to impress once again…

The fix to the CubeCart user agent problem:

1. apply nofollow to the links for login, register and checkout
2. empty the contents of spiders.txt in your cubecart root folder (don’t delete it)
or
2. change user_is_search_engine() to always return false.

To test if your store is affected, use FireFox and check this post on how to change your user agent string, set it to the one I put as an example above and visit your shopsite, then try to add a product to your basket.

update: I am being told that this problem is no longer to be found in current releases of cubecart. Well done, the team :) Now, how many existing customers on versions pre-dating august 2008 have been notified?


Jun 1st 2009 × Windows Vista Wi-Fi lag every 60 seconds – the nightmare of every gamer

If you happen to play games like quakelive or WOW and need your connection to be smooth and without lag, then Windows Vista is going to disappoint you. A lot…

The problem: every 60 seconds or so, Windows Vista does a wireless sweep that looks for any available wi-fi networks in your vicinity. Which is great but in doing so, Vista also causes your game to experience a huge lag spike for about 5 seconds, a gap through which you appear to be ‘warping’ to the other players. Oh, and more often than not, you also get fragged.

Over the course of a 20 minute game, that’s 18 guaranteed spikes of 5 seconds each, totalling over 90 seconds… In other words, a whopping 7.5% of your playing time is spent being lagged out… Go, Microsoft and SP1…

Looking around on Google for a fix has not been very fruitful. Turns out, way too many people get this problem and the solutions are nothing but very inconsistent–what works for one nic / router fails for others. Here is a quick summary of things you can try that I had to go through:

  • a resident tool called Vista Anti Lag which is said to disable the WLAN discovery. It failed to do so on my Intel chipset card, but many people swear by it. Downsides to using VAL (aside from tested support for D-Link only): it does not understand firewalls and crashes if your firewall binds to a dummy adaptor.
  • WLAN optimizer, yet another resident utility, reported to work by some people. Once again, did not work on my Intel 4965 card.
  • running as admin from shell: netsh wlan set autoconfig enabled=no interface=”Wireless Network Connection”, alleged to disable the autoconfig and to replicate the Windows XP Wireless Zero suppression… Downsides: you need to run this each time you have established connection and you need to run the opposite, netsh wlan set autoconfig enabled=yes interface=”Wireless Network Connection” to allow yourself to reconnect. Note: “Wireless Network Connection” should be whatever your have called your connection, this is just the default name. And, yes. It did not work for me.
  • disabling the WLAN Auto Config service. Does not work for me, drops connection and makes reconnecting impossible.
  • using your network card’s manufacturer bridge/connection management software instead of the windows one (in conjunction with previous idea). Intel do not provide anything with their drivers other than a diagnostics toolkit
  • disabling DHCP on your client. Did not work for me.
  • changing your wireless router’s protocol from 802.11 b/g to 802.11 g or b(legacy). Did not work for me.
  • installing the XP version of your nic drivers (network interface card). And yes, that also did not work for me.

So, what did work?
Great thanks need to be extended to SC2008, a user on a German forum who posted his solution called Vista Background Scan (written in Delphi) in this thread. It’s very basic and lacks a proper / intuitive interface but it does what it says on the tin… For the first time ever since I got my new Toshiba laptop, I can enjoy lag-free gaming. Thank you ever so much…

vista background scan in action

Just so that the program does not get lost, I am going to host a local mirror (v0.9) for it (277k). *update* new more stable release is out, get v1.0 here (232k winrar archive). It has now split the wireless devices into a separate tab and is far more stable (i.e. once enabled, you don’t need to freshen it every day).

*update* official website for vista anti lag now exists, visit visit here. Current version is 1.1.1, link is here, but it crashes on my version of vista, so I’ll stick with 1.1 for now.

vista background scan 1.0 in action

Note: at times, VBGScan can stop working even though it’s still running and the optiosn are ticked. If this were to happen, simply click the button / tickboxes a few times and it will kick off again. There’s also a handy utility called Intel WIFI Advanced Statistics which can give you accurate real time data of any Acccess Point (AP) association and confirm with certainty if VBG Scan (or any of the other methods) is doing the business.

If you get any weird errors, start again and just click the big red button, don’t play with the tickboxes.

real time wifi monitoring via intel wifi stats


May 2nd 2009 × our mootools largerBox modal lightbox: it makes you a better man!

largerBox has received a massive update! First of all, the function interface has changed! It now is no longer a snippet, it has been namespaced and organised:

var largerBox = {
    version: function() {
        return 2.1; // 17/05/2009 14:18:40
    },
    init: function(options) {
        // by default it works on image links with the class 'fullImage'

        // set other defaults.
        var options = $merge({
            selector: "a.fullImage",        // can pass on any A object or array of objects, need to contain links to images.
            styleBorder: "1px solid #000",  // border style around image
            useShadow: false,               // apply a css shadow after image is drawn
            useModal: true,                 // use a modal window (toggleModal function) or not
            useTooltip: true,               // uses element.tooltip prototype (needs it defined, set to false if not avail)
            colourModal: "#555",            // default colour for modal,
            imageBackground: "#fff",        // useful to have one for png or gif with transparency
            zIndex: 1000000000              // default z-index for the enlarged images
        }, options);

This post uses the following code to instigate the lightbox on the image above:

largerBox.init({
    selector: "a.newimage",
    useModal: true,
    useShadow: true,
    colourModal: "#fff"
});

The style and effect are somewhat different from our traditional style, visible on the image below:


Anyway, you can grab the latest dci_core library and search for the string largerBox. Dependent functions from dci_core are toggleModal and the element.tooltip prototype, both are optional though.


Apr 27th 2009 × microsoft internet explorer 8 finally released and some IE6 LI floating quirks

Some web dev I am–thanks to google adwords I on this very site I only just noticed an advert by microsoft for downloading IE8… Not how I should have found out about it but it beats not knowing at all, I guess.

I wonder how many issues this will introduce and how complicated my life will soon become… grab it if you have to (no follow link via google)

*update* as I went over to my Microsoft Virtual PC in order to test IE8, I accidentally loaded this site in IE6 and IT WAS HORRIBLE. In particular, it failed to inherit the width of the main content div so it spilled and defaced the site each time any code got posted (affected were code, blockquote and pre tags). Sigh… apologies, reparations have been done now, I just tend to ignore IE6 even though it still amounts to almost 15% of visitors… Even though it has been fixed in part, I should perhaps think of a gentler degradation for IE6 users, one that offers them a chance to upgrade what is now an 8 years old system…

Speaking of IE6 quirks, I had to do a semantic tab system for mootools 1.11 the other day and discovered how IE6 completely messes up the display of LI elements in an ordered list when having nested elements, spilling to the whole available space on the current line instead. The only fix for this is to float the children elements as well… For example:

<li style=”float: left”><strong>this is some text</strong></li> won’t just assume the text’s width, it will span over the whole available width and will push down a line the next LI. You need to float the strong as well in order to achieve the desired effect… Pants!


Mar 16th 2009 × QuakeLive monetisation: it has begun, in-game adverts as of today

Hot off the press, ID have managed to sign on an advertising partner (play.com, no less) for in-game animated banners in QuakeLive that eat away your FPS. Took these screenshots of DM6 earlier with the irresistible offer to purchase the Quantum of Solace DVD…

This really helps my already struggling laptop to cope with things… I wonder if there will be an adblock plus version for QuakeLive :)


Mar 9th 2009 × Internet Explorer 8 RC1 and IE7 compatibility mode: not really compatible

Lately I have been playing with the RC1 release of IE8 and to my shock-horror, it makes a total mockery of many of the pages I administer and run. To the rescue is the so called ‘compatibility’ mode, created as a layer that allows your sites to look, feel and function exactly as they did in IE7. Allegedly, the magic code is:


<meta http-equiv="X-UA-Compatible" content="IE=7" />

My initial testing concluded that it seemed to do the job and I let it rest, hoping to have survived yet another Microsoft blunder on the cheap… Not so. Turns out that you still get differences and issues in CSS. This is non-fatal but the fact that certain JS scrolling modules I had written now seemed to output nothing at all worried me. A google search revealed that Microsoft are managing a list of 2500+ sites, submitted by testers and reported to still have problems despite of the compatibility layer! Nice… I guess I will be submitting my own entries — and so should you… As if the Safari 4 beta was not bad enough…

Word to the wise, do not install a RC (release candidate) on a machine that you value – to be safe, download a copy of the Microsoft Virtual Machine and an XP image, then install on it.


Feb 16th 2009 × E-commerce and product search algorithms: get relevant search results, not just random DB dumps

Everyone has been down that route – trying to make a good search. Most have failed…

The one thing that really annoys me when shopping around are searches on sites that give you irrelevant results. For instance, take a search for ‘black pack’ – I think you’d agree, a generic string with which I’d expect to get ‘backpacks’ and ‘daypacks’ and the likes, in black. For the experiment, I have chosen a site at random from google: gooutdoors.co.uk (see the search results yourselves here, in a new window). NB: I am in no way affiliated with gooutdoors.co.uk and this is not a dig at them or a link back for their site in any way, I have even applied a nofollow tag to the results link

When you had expected to see backpacks and got things like “Silva Ranger 3 Compass”, “Lifesystems HeadNet Mosquito Hat” and “Wayfayrer Beef Stew and Dumplings” (sic) instead, you can’t help but think something has gone terribly wrong with the search script. With over 70% of users likely to just ‘bounce’ off such a site after not being able to find what they were after immediately, we need to take a look into the why’s of getting such irrelevant search results.

Upon clicking on the Lifesystems Mosquito Hat from the above result set and scanning for the words ‘pack’ and ‘black’, we notice them within the product features:

  • Can screw down into a small “stuff pack

  • Ultrafine black mesh

Should these results have been displayed to me? No. Why do we get this problem? Lazy coding. The most basic search practice out there is to do something like:

1. Break string into words.
2. Compose the search query targeting known data fields like title, description, features, word by word, imploding into the query. At this point the where statement can look like ‘where (description like ‘%black%’ or features like ‘%black%’ or title like ‘%black%’) and (description like ‘%pack’ … etc etc)
3. Display the results and hope for the best.

There’s a marketing school of thought here that you’re better off displaying ‘something’ than no hits – but this is NOT how it’s done. Here is another favourite search of mine that works on the site above:
the this, Found 253 product(s) – page 1 of 22

It’s fair to say, certain words should not be used to score results, they are just too generic to be considered. Unless you are typing something like ‘the north face’, ‘the’ should be dismissed, in the same way as ‘this’ should be removed. In fact, over time — I have built a database of ‘bad keywords’ to drop from search strings that you can see as an appendix to this post.

So, what is the alternative? Oddly enough, I have found the most accurate search results are achieved via manual tagging and backed up by product knowledge. It goes like that:

1. Assign tags to each product. You can build an aliases table for common tags and errors. For example, you want to alias things like berghaus with berghouse, berghaus, burghaus etc (you’d be surprised how many people make mistakes).
2. Build the search algorithm to break down the string into parts and analyse them. Drop all common words that won’t help and keep the ‘useful’ bits only (See below for badwords)
3. What words you have left, treat as tags and fetch all products they have been applied to.
4. Refine for relevance. This is done by assigning a number score of hits on a product. Basically – If I search for Berghaus RG1 Jacket, that’s a possible 3 tagwords score. If the shop has the RG1 in stock, the listings should ONLY show me that result (or any other 3 point hits) and none of the results with 2 or less (jacket + berghaus). If the RG1 is not being stocked, this leaves an array of jackets by Berghaus and an array of jackets. Once again, go for relevance and show the first group of results only.

Advantages: always gets the right and relevant results, providing good product maintenance.
Disadvantages: needs to be managed, needs to be updated and there’s a need to monitor for people’s mistakes in searches and allowing for them.
Bottom line: The increased conversion ratio will justify the man hours put into tagging your product base. It’s a credit crunch, we all need to work harder!

I hope this gives you some ideas anyway.

Here is a suggested list of ‘bad words’ that can be safely dropped from search strings:

$badwords = array(
"a", "a's", "able", "about", "above", "according", "accordingly", "across", "actually",
"afterwards", "again", "against", "ain't", "all", "allow", "allows", "almost", "alone",
"along", "already", "also", "although", "always", "am", "among", "amongst", "an", "and",
"another", "any", "anybody", "anyhow", "anyone", "anything", "anyway", "anyways", "anywhere",
"apart", "appear", "appreciate", "appropriate", "are", "aren't", "around", "as", "aside",
"ask", "asking", "associated", "at", "available", "away", "awfully", "b", "be", "became",
"because", "become", "becomes", "becoming", "been", "before", "beforehand", "behind",
"being", "believe", "below", "beside", "besides", "best", "better", "between", "beyond",
"both", "brief", "but", "by", "c", "c'mon", "c's", "came", "can", "can't", "cannot", "cant",
"cause", "causes", "certain", "certainly", "changes", "clearly", "co", "com", "come", "comes",
"concerning", "consequently", "consider", "considering", "contain", "containing", "contains",
"corresponding", "could", "couldn't", "course", "currently", "d", "definitely", "described",
"despite", "did", "didn't", "different", "do", "does", "doesn't", "doing", "don't", "done",
"down", "downwards", "during", "e", "each", "edu", "eg", "eight", "either", "else",
"elsewhere", "enough", "entirely", "especially", "et", "etc", "even", "ever", "every",
"everybody", "everyone", "everything", "everywhere", "ex", "exactly", "example", "except",
"f", "far", "few", "fifth", "first", "five", "followed", "following", "follows", "for",
"former", "formerly", "forth", "four", "from", "further", "furthermore", "g", "get", "gets",
"getting", "given", "gives", "go", "goes", "going", "gone", "got", "gotten", "greetings",
"h", "had", "hadn't", "happens", "hardly", "has", "hasn't", "have", "haven't", "having",
"he", "he's", "hello", "help", "hence", "her", "here", "here's", "hereafter", "hereby",
"herein", "hereupon", "hers", "herself", "hi", "him", "himself", "his", "hither",
"hopefully", "how", "howbeit", "however", "i", "i'd", "i'll", "i'm", "i've", "ie", "if",
"ignored", "immediate", "in", "inasmuch", "inc", "indeed", "indicate", "indicated",
"indicates", "inner", "insofar", "instead", "into", "inward", "is", "isn't", "it",
"it'd", "it'll", "it's", "its", "itself", "j", "just", "k", "keep", "keeps", "kept",
"know", "knows", "known", "l", "last", "lately", "later", "latter", "latterly", "least",
"less", "lest", "let", "let's", "like", "liked", "likely", "little", "look", "looking",
"looks", "ltd", "m", "mainly", "many", "may", "maybe", "me", "mean", "meanwhile", "merely",
"might", "more", "moreover", "most", "mostly", "much", "must", "my", "myself", "n", "name",
"namely", "nd", "near", "nearly", "necessary", "need", "needs", "neither", "never",
"nevertheless", "new", "next", "nine", "no", "nobody", "non", "none", "noone", "nor",
"normally", "not", "nothing", "novel", "now", "nowhere", "o", "obviously", "of", "off",
"often", "oh", "ok", "okay", "old", "on", "once", "one", "ones", "only", "onto", "or",
"other", "others", "otherwise", "ought", "our", "ours", "ourselves", "out", "outside",
"over", "overall", "own", "p", "particular", "particularly", "per", "perhaps", "placed",
"please", "plus", "possible", "presumably", "probably", "provides", "q", "que", "quite",
"qv", "r", "rather", "rd", "re", "really", "reasonably", "regarding", "regardless",
"regards", "relatively", "respectively", "right", "s", "said", "same", "saw", "say",
"saying", "says", "second", "secondly", "see", "seeing", "seem", "seemed", "seeming",
"seems", "seen", "self", "selves", "sensible", "sent", "serious", "seriously", "seven",
"several", "shall", "she", "should", "shouldn't", "since", "six", "so", "some", "somebody",
"somehow", "someone", "something", "sometime", "sometimes", "somewhat", "somewhere", "soon",
"sorry", "specified", "specify", "specifying", "still", "sub", "such", "sup", "sure", "t",
"t's", "take", "taken", "tell", "tends", "th", "than", "thank", "thanks", "thanx", "that",
"that's", "thats", "the", "their", "theirs", "them", "themselves", "then", "thence", "there",
"there's", "thereafter", "thereby", "therefore", "therein", "theres", "thereupon", "these",
"they", "they'd", "they'll", "they're", "they've", "think", "third", "this", "thorough",
"thoroughly", "those", "though", "three", "through", "throughout", "thru", "thus", "to",
"together", "too", "took", "toward", "towards", "tried", "tries", "truly", "try", "trying",
"twice", "two", "u", "un", "under", "unfortunately", "unless", "unlikely", "until", "unto",
"up", "upon", "us", "use", "used", "useful", "uses", "using", "usually", "v", "value",
"various", "very", "via", "viz", "vs", "w", "want", "wants", "was", "wasn't", "way", "we",
"we'd", "we'll", "we're", "we've", "welcome", "well", "went", "were", "weren't", "what",
"what's", "whatever", "when", "whence", "whenever", "where", "where's", "whereafter", "whereas",
"whereby", "wherein", "whereupon", "wherever", "whether", "which", "while", "whither", "who",
"who's", "whoever", "whole", "whom", "whose", "why", "will", "willing", "wish", "with",
"within", "without", "won't", "wonder", "would", "would", "wouldn't", "x", "y", "yes", "yet",
"you", "you'd", "you'll", "you're", "you've", "your", "yours", "yourself", "yourselves", "z", "
);