December 18, 2012

Ticketing & Locking

We provide services to facilitate communication between us and our distributors. This application is called "contacts". Any contact request can only be updated by one party at a time (it is locked while someone has the page open), but the person who logged the question is always able to view the request.

Today I received a mail about an issue with the locking system. Our customer was told that their contact request was under treatment by themselves and that they could not update it while someone else was editing.

After spending a while trying to figure out under which circumstances a contact was locked and unlocked and not being able to find anything (seriously) wrong with it I looked a bit further.

Turns out that the column in the table that stores who locked the contact contained the name of the user instead of the (expected) user-id.

The fun part was this: This column was limited to 20 characters and the users' name was longer than that. The result? A concatenated string and the comparison that goes wrong everywhere, considering the actual contact owner and the person who locked the request as 2 different ones.

Welcome to the world of non-programmers writing code.

October 04, 2012

The life of a Fixer #2

PHP: How to convert a date into a different format

$timestamp = explode(' ',$transaction['datetime']); // 2008-04-28 17:40:19
$date = explode('-',$timestamp[0]);
$date = $date[2].'/'.$date[1].'/'.$date[0];
$time = substr($timestamp[1],0,5);
$datetime = $date.' '.$time; // 28/04/2008 17:40


Javascript: Drag and drop with different processes

So we have a callback function for a drag and drop script that was found on the web somewhere and we have a box called IN where we can drop "products" on. 

Some of the thoughts we have during development of "this solution":
  • Of course we write a single function of about 400 lines of code, it's cooler that way.
  • We need to check the drop target as it needs to have a specific ID, so we do some getElementById magic.
  • Oh crap, now we also need an OUT box. We have a couple issues here... The drop box for that one has a different ID (a '2' was appended, obviously!). Also: sometimes we have to show a prompt and the text there needs to be different. Conclusion: We can't possibly re-use the code from the other box! Let's just copy/paste all 400 lines and make a different function (ah and of course, add a '2' to the name).
  • Hmm crap... The customer seems to work with internet explorer. The one line of code that checks the drop target does not work there. Easy fix! Let's just take the entire javascript file, copy it into a "script-ie.js" file. And presto, we include that one if the customer has IE. Modifying 4 functions every time? No problem!
  • Hmm we appear to have 2 kinds of products. The ones that need to go through the ERP system and products that remain local to the shop. How do we handle that? Simple! We just add an asterisk before the name to indicate the difference. Actually we thought about this a lot, since there are way less local products, we show the asterisk for those. Our customers won't wonder at all what a "* name of the hardware" is (no there aren't any footnotes at the end of the page).
  • So now we have to ask a serial number for some of the products. How do we indicate that? Yes of course, you guessed it already! We just add another asterisk, but AFTER the product name! We cant do 2 before the name, how would we know which one stands for what? You silly! So yeah... "*I'm a local product and I need a serial*". It's gotta be clear what this means, no?

The life of a Fixer


So, for those of you who don't already know: I've recently stepped into my own business fulltime. I work as a freelancer for a company that has outsourced me to another company as a consultant. (Yeah complicated,  I know).

In that company ("the client") I'm taking care of all the internally used PHP applications. Internally I'm what they refer to as "a fixer" and boy that expression holds some serious truth.

Most of the tools were originally written by non-developers (basically by anyone that had some web-experience and needed some kind of tool to get something done) and unfortunately it shows.

Now mind you, they are doing everything humanly possible to clean all this up, I wouldn't be here if they weren't. So in no way do these posts say negative things about the company as a whole, this is just about the legacy they have to deal with on a daily basis. I consider it my mission to improve their code while I'm maintaining it, but unfortunately it will take a while.

And... ?

Well as you might already suspect, I've been working there for a month now and I used up my "WTF!?" quota for the next 5 years. Which is why I figured I might as well share some stuff with the world :-)

Unfortunately I've missed a lot of good ones already, perhaps I'll recall enough details one day to still post them, but I'm sure there's more than enough stuff remaining :-)

A lot of these assume you know a thing or 2 about web development, which is why I'm putting them all under nerdy and webdev (and definitely WTF!).

Why not The Daily WTF you might ask? I don't want to fill up their news queue for the next year ;-)

Here we go!

A very urgent ticket was created yesterday. When arriving on the target site whilst not being logged in, you would get an error after logging in there. (Invalid template).

Some investigating later we determined that the user was correctly redirected to the login form if still anonymous, but that the redirect back to the originating page seemed to lose the query parameters.
This of course resulted in the described error, as the target page did not know what article to show.

Easy fix right? Figure out where the access check is done and make it include the query string as well. Mind you, for once this actually was the problem! Unfortunately as with everything I encounter here, there's more!

The code that did the check was in the actual target file. Not an included file, not a class... the actual source file. I'm pretty sure this will cause "oh shit" thoughts in every developers' head.

So we have an "isAuthorized"-function and a piece of regular code below, with a lot of MM_ prefixes (ah MacroMedia Dreamweaver stuff... nostalgia!).

A search later (a lot of doubting on whether I should actually do that) it turns out that the same snippet (function AND regular code) is copy/pasted into every one of the 253 entry scripts.

The allocated budget is limited to just this one fix, so there's no fixing the rest... So we log a "problem ticket" about the 252 other cases (that have the same bug but aren't currently considered an issue). If the customer ever approves that ticket we'll handle those. 'til then it's 252 pieces of buggy code!

See you on the one ;-)

June 07, 2012

Hurray voor de CBPL! (en in your face stad Mechelen)

Since this post is local to Belgium and more specific Mechelen, I'm going to write it in Dutch. My apologies to the English speaking folks following my blog (if any ;-) )

Waarover gaat het?

Vlak nadat ik een bouwvergunning aanvroeg in Mechelen om renovaties te doen aan mijn woonst, begon ik van een hoop bedrijven van bouwmaterialen geadresseerde reclame te krijgen. Elke dag zat er wel een ander stuk in mijn bus. Ik heb zelf een hartsgrondige hekel aan reclame, er kleven niet voor niets 2 NEE stickers op mijn brievenbus (wat de ronddragers overigens nog steeds niet tegenhoud). 

Kun je niets tegen beginnen, toch?

Toen de vloed aan reclame niet stopte besloot ik om een klacht in te dienen tegen Stad Mechelen bij de CBPL (Commissie voor de Bescherming van de Persoonlijke Levenssfeer). Zo'n praktijken kunnen gewoon niet meer.

Na ettelijke maanden over en weer mailen (want snel zijn ze helaas niet) en de nodige bewijsstukken (reclame dus) over te maken, heb ik vandaag dan toch een brief gekregen die mij hoop geeft. 

De CBPL heeft heel deze zaak heel grondig opgevolgd. Ze heeft de stad Mechelen meermaals om verantwoording gevraagd (met 2 herinneringsbrieven tussendoor wegens geen antwoord). Uiteindelijk is Mechelen dan toch in beweging gekomen en daar heb ik vandaag verslag van gekregen.

Wat dan?

Sta me toe een deel van de brief openbaar te maken:
Geachte heer,
Ik verwijs hierbij naar mijn e-mail d.d. 31 januari 2012 waarin ik u beloofde u op de hoogte te brengen van het antwoord van de Stad Mechelen.
 Na het versturen van twee herinneringsbrieven aan de stad Mechelen heeft de Commissie op 23 mei 2012 een antwoord ontvangen.
Uit hun antwoord blijkt dat bij de controle van de verwerking van de persoonlijke gegevens, na de beslissing van het College van burgemeester en schepenen, de gegevens worden doorgegeven aan het Kadaster en aan het Nationaal Instituut voor statistiek. De gegevens worden ook doorgegeven aan zogenaamde "niet-relevante" instantie (Belgacom, Bouwkroniek, BTW, Confederatiebouw, Electrabel, Pidpa, Polder). Dit systeem is blijkbaar al vele jaren een gewoonte.
 Naar aanleiding van het schreven van de Commissie heeft het College van burgemeester en schepenen beslist dat er geen gegevens meer worden doorgegeven aan niet-relevante instanties.

W00t zou ik zo zeggen! Ik heb er zelf niets meer aan, moet me nog altijd van al die adreslijsten zien te krijgen, maar aan de toekomstige bouwvergunnings-aanvrager: You're welcome! :-)

Ik weet niet waarom ze het al jaren zo doen, maar het hoort gewoon niet. Ik heb letterlijk weken aan een stuk 3 tot 4 stukken reclamedrukwerk per dag gekregen. 

January 20, 2012

MacOS Lion: Slow Disk?

In September I bought a brand new iMac with 8GB RAM and a regular harddisk. Even though it should've been a work horse, it wasn't. The CPU itself was never really loaded, but everything that required disk access seemed to be ULTRA SLOW. When the disk was under heavy load, the swiping between desktops would just hang halfway a slide and so on.

I guess I don't have to mention that, given the price of one of those Macs, this was extremely frustrating.

It even annoyed me up to the point that I actually called Apple to ask how much it would cost me to add an SSD. Unfortunately the price tag (about 800 euro's) was a bit too steep for my wallet. Apparently the back cover of the iMac has different configurations as well and if you buy a Mac with a regular disk alone, it has no bracket to mount the SSD. So its not SSD + hours but also the price of a new back cover. So people: Think before you buy! An SSD is a really good investment and it will cost you half that price when you add it right at the start.

Anyway, back to the point: I recently found this little post on one of the mac boards about that issue. Since I had Quicksilver installed, I thought like: Eureka! Nothing else had worked before. The minute I disabled it it became apparent that that was indeed the root cause of the extremely slow disk! The Mac now behaves as I would expect it.

So people if you run Lion: Don't use Quicksilver!