The HRS touch interface and why it sucks

I like to be ahead of the game. Not only as a softball umpire but also on my vacation trips. The two guys I’m with on vacation picked hotels on a try-and-error basis in the first days. But just stopping at the first hotel that comes in sight neither gives you the best prices nor the best hotels, so I jumped in and took over the hotel management.

I book everything through HRS. This is not because they have the greatest platform on earth but they have a lot of hotels around the world. But speaking of the platform, hell it sucks. Especially the touch interface. It starts with this modal overlay that tell’s you that they are gathering the search results. Have you ever seen something similar on Google? No? That’s because it’s completely unnecessary and bloats the interface. And I built a hotel reservation system on my own a few years ago, I know what I’m talking about!

Location awareness? Not with HRS. We stayed one night in London. London, Ontario to be exact. While Google offered me the canadian London as a first choice in the Maps app HRS always offered London, England first. It’s so easy to get this right based on IP or location! And yes, HRS is allowed to use my location.

Browsing through the results is slow as hell. Because every time you select a hotel you get this fancy overlay. And every time you go back to the result list, you get it again.

Currency conversion: I have no idea what they are smoking. In the result list it is converted correctly, 103 Canadian Dollar equals more or less 75 Euro. In the detail view on the offer tab however, this becomes 149 Euro, but still 103 Canadian Dollar.

Error handling: What a mess! Filling forms on a mobile device is a pain in the ass by default. But it get’s worse with the error handling HRS implemented. Got a typo on your 16 digit credit card number? No problem, a model overlay will let you know and you can correct it. For your convenience HRS deletes both the whole number and the name on the card. Once fixed you get an error 5000, ‘Person invalid’. This time, you can’t correct it. You are thrown back to a blanked out search form. HRS yells in your face: „Don’t make any typos, stupid! So start over completely again till you learned your lesson”.
Because you are already annoyed you skip the second person on a double room as the fields are marked optional anyway. Well, obviously this is no longer true but the backend guy forgot to tell the frontend guy. You might already know what happens: Model overlay that says to fill in a first name for the second person. After fixing this (and typing your credit card number once again as HRS blanked the field for your convenience) you get: Error 5000. Welcome back home, baby! I was that close to calling the hotel and book by phone, but it worked on the third try. Once again when you are dominant in your market you get lazy, as HRS does.
The good thing is: I can tell my credit card number from memory now and impress front desk clerks all over the world with this useless trick.

Going Android

My day-to-day phone still is an iPhone 4S, netlocked thanks to Deutsche Telekom. So I was in need for another phone for my recent trip to the US and Canada. From my collection auf test devices I picked the Nexus 4 with the latest Android OS. We are now on the road for more than a week and, while cruising around Lake Superior on the Trans-Canada Highway, it’s time to write a short review.


Before leaving I ordered an AT&T SIM and a voucher from travelSIMple which I activated while still in Germany. I went off the plane in Chicago and had data instant on. That’s really great. What’s not so great is the size of the phone. It’s both taller and wider than my iPhone and that sucks. There are tasks on Android where you have to reach the upper left corner on the phone and I always have to change the position of the phone in my hand or I use my other hand.

It happens all the time to me that I hit the wrong button when I want to unlock the phone. When you draw the phone from your pocket you can’t tell where is up and down as there is no real home button. And putting the unlock button on the side doesn’t make that in any way easier.

What I miss most is to scroll up all the way by a simple press on the title bar. But I guess, there’s an app for that, as I also had to install an app to prevent the display from rotating. You’re kiddin’ me, right?

What also works on a good-luck-basis is locking the phone, especially when you use the standard slide unlock. I happend more than once that my phone was unlocked and doing weired things while sitting in my pocket. I switched to a pin code and it never happend again. Still ridiculous.

What’s really great is the spell correction. It happens to me quite often on the iPhone that I select a correction on error. You have to delete everything then. On Android when this happens and you hit backspace it reverts to the word it corrected from. I love this as I love the abbility to pick from three different suggestions. However, sometimes hitting space does exactly nothing and you come up with concatenated words that shouldn’t. I think this is related to the spell correction but I wasn’t able to figure this out yet


I have a very limited set of apps on the phone, only those I really need while on vacation.


This includes K9 Mail for my regular email. This is a great app, supports multiple accounts, colors for the accounts and is a full-fledged IMAP client. Missing a swipe-to-delete gesture in list view, however.

I use the GMail client that ships with the phone and this one is so much worse than the current iPhone client. Makes me wonder what Googles primary platform really is. You can’t batch delete mail by tapping a checkbox in list view, you can only archive on swipe but not delete and assigning labels drives my crazy every time as it is an unnecessary multi-step process.


The built in Maps app is, compared to the GMail app, so much better. I use it for navigaton, it has a real small data usage footprint and good directions. I’m somewhat confused with the multiple search input fields that return different result views and I haven’t figured out yet how to start a navigation from my current location once I delete the current location entry.
Quite funny is the voice on navigation. The phone is set to German as it’s primary language and the navigation tries to pronounce all street names in German. There’s room for improvement…


I love the Foursquare widget on the home screen. I check in quite more often than I do on my iPhone. Otherwise this app is not much different from the iPhone app.


I’m a hardcore user of Panic’s Prompt on the iPhone. I did a lot of research and finally installed ConnectBot. Well, it’s not yet competitve but as far as I can tell it’s the best you can get.

  • There is now way to import keys, you have to generate a key on the device and then introduce the public key to your server. This means some work when you have more than two servers (as I do). And even then connection with keys isn’t the default, so connection takes some time as password based has to fail first.
  • You can’t rename bookmarks. I have quite a few connections to the same server with numeric usernames. You just can’t tell them apart when you can’t give the bookmark a name. I had to set up subdomains to do so.
  • You can’t read anything on the prompt by default. You have to reset the terminal to a given size. And you have to do this every time. Pinch gestures don’t work.
  • No arrow keys. If you want to do execute the same command again you have to type !! every time.



As mentioned above I got an AT&T SIM from travelSIMple before leaving. The internet coverage is quite amazing, even in not so densly populated areas, buying extra data is easy, tethering works out of the box and like a charme. In brief, im quite happy with AT&T.


On the other hand, Rogers sucks. Big time. I go with the claim ‘Where I am is internet’ so I couldn’t risk to be without while in Canada, even if it’s only for four days (things somewhat change when you are self employed). I got a Rogers SIM, also from travelSIMple, but you can’t activate it from abroad.
This is because you need either a canadian credit card (which I don’t have) or a voucher. Unfortunately you can’t buy vouchers before, because they are only valid for 30 days and expire afterwards without any refund. This is ridiculous and I’m happy to live in Germany where those things won’t happen. Next problem: These vouchers are pretty hard to get. I tried right after the border where you can get fishing and hunting permits, but no Rogers vouchers. I tried on a truck stop to no avail. Finally, I got lucky at a Walmart.
Nontheless, network coverage by Rogers is pretty good. I had no activated SIM around the north shore of Lake Superior, so AT&T dropped to Rogers roaming. I had coverage almost on the whole Trans-Canada Highway 17, however, as I was on roaming and not interested in getting bankrupt, I can’t tell if and who good data coverage would have been.

You can’t fix what’s not broken, 1&1

You can surprise people when you tell them you own more than 100 domains. Currently I have 118 domains in my portfolio. Some have website or mail services, some are for later use and some just redirect to another domain. This is the case for the domain in question.

I received an email from 1&1 last thursday telling me the website at is infected. Indeed, the website shows a warning page when accessed with Google Chrome, however, it redirects to This is the infected website. So I told 1&1 that this is a false positive because this is just a redirect and the domain the redirect points to is not under my control. I also asked them to check their systems so they don’t bother me with these false positives in the future.

The reaction was exactly what you expect from 1&1: They told me (which was not infected) is under my control and I should fix this ASAP. Well, you can’t fix what’s not broken and so I send them a screenshot with the following:

matthias:/htdocs/ # ls -al
total 8
drwxr-x---  2 examplecom   psaserv   22 2011-03-01 10:22 .
drwxr-xr-x 13 root         root    4096 2011-04-10 21:48 ..
-rw-r--r--  1 root         root      66 2011-03-01 10:22 .htaccess
matthias:/htdocs/ # cat .htaccess
RewriteEngine On

RewriteRule .* [L,R=301]
matthias:/htdocs/ #

So I have done exactly nothing but 1&1 congrats me for solving this issue. They don’t get the point. And because of that I will have to life with these false positives in the future.

Kellermeister mit Weinasche

Ich arbeite gerade an einem neuen Shop und dem Kollegen auf seinem Ubuntu 10.10 ist dabei aufgefallen, dass Buchstaben fehlen. Das Produkt heißt dann eben nicht mehr Kellermeister mit Weinflasche, sondern Kellermeister mit Weinasche und auch nicht Hirt mit Vogelkäfig, sondern Hirt mit Vogelkäg.

Ziemlich eindeutig ein Problem mit Ligaturen. Ich hab’s dann erstmal auf Linux geschoben und ignoriert. Dann hat mich aber doch der Ehrgeiz gepackt. Das ganze auf Firefox als schuldigen eingegrenzt und tatsächlich auf einen alten Beitrag von Peter Kröner gestoßen. text-rendering: optimizeSpeed; bringt dann auch das gewünschte Ergebnis unter Ubuntu 10.10 und der Käfig heißt nicht mehr Käg. Die Gegenkontrolle im Firefox auf dem Mac zeigt, dass das Problem weiterhin besteht, also die Lösung von Peter nur auf alte Firefox-Versionen eine Auswirkung haben. Will man auch den aktuellen Versionen diese Unart austrieben braucht man noch zusätzlich:

-moz-font-feature-settings: "liga=0";

Das schaltet die Ligaturen dann wirklich ab. Das Problem scheint nur bei manchen Webfonts aufzutreten, bei denen von Google konnte ich es bislang nicht beobachten, bei der hier verwendeten LHF Hensler von Letterhead Fonts hingegen schon.

Webseiten-Infektion mit gestohlenen Plesk-Passwörtern

Oder auch: The Sicherheitslücke strikes back. Im März machten Meldungen die Runde, dass eine Lücke im Plesk-Admin dazu genutzt werden konnte, um administrativen Zugriff auf das System zu erhalten. Wie sich jetzt zeigt hätte Plesk den Hinweis, doch man nach dem Einspielen des Patches alle Passwörter zu resetten, wesentlich plakativer auf die Seite schreiben sollen.

Wieso? Während wir uns vor kurzem noch darüber kaputt gelacht haben, dass LinkedIn Passwörter mit SHA1 ohne Salt verschlüsselt geht Plesk noch einen Schritt weiter, um es dem Angreifer möglichst einfach zu machen: Sie verschlüsseln die Passwörter erst gar nicht (bzw. erst seit Version 11). Wer also gedacht hat, dass das Problem mit dem Einspielen des Patches aus der Welt sei, weil eventuell gestohlene Passwörter ja erst geknackt werden müssten: Think again.
Besitzer von Plesk bis zur Version 10 können zur Beweisführung folgendes machen:

cat /etc/psa/.psa.shadow

präsentiert das Root-Passwort für die MySQL-Datenbank (das auch gleichzeitig das Admin-Passwort für Plesk ist) im Klartext. Und das ist nicht einmal ein Geheimnis, in der Plesk-KB wird genau das als Lösung beschrieben, sollte man mal sein Passwort vergessen haben!
Und auch sämtliche Passwörter für das Admin-Panel stehen unverschlüsselt in der Datenbank. Wer also einen Blick in psaaccounts wirft sollte sicherstellen, dass er sitzt.

Passwörter, die durch die Lücke im März gewonnen wurden, werden derzeit aktiv genutzt, um Webseiten zu kompromitieren. Aktuell wohl überall mit dem gleichen Schadcode, der in php, asp(x), html und js-Dateien eingefügt wird und bislang noch ziemlich eindeutig daran zu erkennen ist, dass er zwischen den Kommentaren /*km0ae9gr6m*/ und /*qhk6sa6g1c*/ eingeschlossen ist.
Da der Angriff über den Plesk-Admin stattfindet zeigen sich in den Logfiles der betroffenen Webauftritte keinerlei Auffälligkeiten. Die findet man aber in den Plesk-Access-Logs unter /usr/local/psa/admin/logs/ bzw. im Activity-Log, das man sich über die Plesk-Oberfläche laden kann. Aus letzterem geht auch hervor, mit welchem Benutzernamen zugegriffen wurde. Anders als bei UnmaskParasites aber vermutet gehe ich von automatisierten Angriffen aus, die Einträge im Log sind viel zu dicht beieinander als das da jemand manuell klicken würde.


Nach meinem aktuellen Kentnisstand wird außer dem Einschleußen des Codes nichts weiter mit dem Server gemacht – obwohl man quasi alle Möglichkeiten hätte.

  • Zunächst gilt es also, sofern noch nicht geschehen, den Patch einzuspielen.
  • Danach durchsucht man den Server nach infizierten Dateien und säubert diese. Unter Linux kann man dazu grep und sed benutzen. Unter Windows wird man um eine Analyse des Plesk-Access-Logs nicht herumkommen.
  • Abschließend setzt man alle Passwörter zurück. Von Plesk gibt es ein entsprechendes Script.

Zusätzlich kann man noch folgendes machen:

  • Wer die Netze, von denen Zugriffe auf den Plesk-Admin erfolgen, klar definieren kann, kann den Zugriff auf dem Admin entsprechend einschränken: EinstellungenAdministratorzugriff einschränken.
  • Den Plesk-Admin mit einem serverseitigen Passwortschutz versehen. Eine entsprechende Anleitung findet sich hier.

Krisenmanagement bei 1&1

In der Krise zeigt sich, was der Provider wirklich drauf hat. Krise bei 1&1 war gestern. Und das Krisenmanagement hat sich mit der Internetleitung einen Wettstreit darum geliefert, wer von beiden der größere Totalausfall ist.

Los ging es um kurz vor drei. Fünf von fünf Servern nicht erreichbar. Ein kurzer Check über die serielle Konsole ergab aber, dass es nicht an den Servern lag. Der Twitter-Account @1und1 brauchte dann geschlagene 20 Minuten, um das auch zu bemerken. Die, man sollte annehmen eigentlich genau für einen solchen Fall gedachte, Statusseite hingegen verkündet auch heute morgen noch, dass alle Systeme funktionieren würden und dies seit dem 4. August so sei.

Ziemlich genau zwei Stunden später waren dann alle Server wieder erreichbar bis kurz vor 20 Uhr. Und hier kommt der Teil, der mich an dieser Geschichte wirklich aufregt. Fehler können immer mal auftreten, da kann man sich noch so gut absichern. Und ich gestehe jedem eine angemessene Zeit zu, dass er diese beheben kann. Wenn man aber um kurz nach fünf mit großen Halali auf Twitter verkündet, dass jetzt wieder alles gut sei, dann sollte man alles daran setzen, dass nicht genau der gleiche Fehler kurz darauf wieder auftritt:

Die Ursache ist bekannt. In anderen Worten:

Scheiße, genau das gleiche wie vorhin. Warum haben wir das nicht einfach vernünftig gefixt?

Und obwohl 1&1 weiß, woran es liegt, brauchen sie erneut über zwei Stunden, um das Problem aus der Welt zu schaffen!
Krisenmanagement und vor allem auch Krisenkommunikation sieht anders aus. Die angesprochene Statusseite hat sich auch beim zweiten Ausfall nicht aktualisiert und der Twitter-Account war eigentlich immer so viel zu spät dran, dass man sich auch den hätte sparen können.

Konfigurierbare Produkte mit individuellen Preisen

Bei manchen Funktionalitäten, die in Magento eingebaut sind, fragt man sicht schon, ob man bei Varien mit dem, was man sich da zusammenklöppelt, auch einen Praxisbezug sieht oder ob man einfach irgendwas programmiert, egal ob es in der Praxis brauchbar ist oder nicht. Die Preisvergabe bei konfigurierbaren Produkten ist so ein Fall. Magento sieht von Haus aus vor, dass man einer Variante, etwa einer anderen Größe, einen festen oder prozentualen Aufpreis geben kann. Oder anders gesagt, die untenstehende Preismatrix funktioniert mit diesem System schon nicht mehr:

  11cm 15cm
natur 28,40 31,80
Goldrand 31,20 34,90
lasiert 34,60 40,70

Denn bei natur kostet die 15cm-Variante 3,40 Euro mehr, bei Goldrand aber schon 3,70 Euro und bei lasiert gar 6,10 Euro. Das lässt sich weder durch einen Fixpreis noch durch einen prozentualen Aufschlag abdecken und wenn man dann noch bedenkt, dass man das auch noch für die Ausführung (natur, Goldrand, lasiert) machen muss bricht das ganze System in sich zusammen.

Zum Glück gibt es eine Lösung, die eigentlich so naheliegend ist, dass man sich fragt, warum Magento das nicht einfach von Haus aus kann: Simple Configurable Products. Die Erweiterung sorgt dafür, dass einfach der direkt beim Produkt hinterlegte Preis benutzt wird. Und nicht irgendwelche komischen Berechnungen durchgeführt werden, die am Ende doch nicht zum gewünschten Ergebnis führen.

Einen kleinen Bug hat die Erweiterung aber: Zeigt man die gewählte Option im Warenkorb an, dann wird immer das Admin-Label für das Attribut verwendet, welches nicht mehrsprachig ist. Aber dafür gibt es Abhilfe. Die Datei, um die es geht, ist Checkout/Block/Cart/Item/Renderer.php. Dort findet sich in Zeile 81:

'label' => $attribute->getFrontendLabel(),

Das muss lediglich durch

'label' => $attribute->getStoreLabel(),

ersetzt werden und schon sind die Label auch in der jeweiligen Store-Sprache.

Umlaute im URL key von Magento

Umlaute ist ja eines meiner Lieblingsthemen. Und Magento stellt sich da direkt hinter Afterbuy in die ‘Können wir nicht’-Schlange. Naja, fast. So heißt es in meinem Lieblingsbuch auf Seite 162:

Die URL-Bezeichnung ist wichtig, wenn Sie als Shop-Besitzer die Anzeige in der Adressleiste eines Browsers beeinflussen möchten. Sollten Sie das Feld leer lassen, generiert Magento automatisch aus dem Produktnamen die URL-Bezeichnung. Da das System aus dem USA stammt, werden die Umlaute dabei nicht berücksichtigt, sondern falsch dargestellt: ä als a, ö als o etc.

Soweit richtig. Magento berücksichtigt in der URL-Bezeichnung (URL key) keine Umlaute. Warum man im Buch aber nicht direkt auf die Lösung verweist erschließt sich mir nicht. Denn wer mag schon bei vierstelligen Produktzahlen jeden URL key in Handarbeit erstellen?

Allerdings muss die im Magento-Wiki befindliche Lösung noch etwas erweitert werden, denn die Einträge in app/etc/local.xml, die im Wiki genannt werden, berücksichtigen weder ß noch die Großbuchstaben Ä, Ö und Ü (die Ersetzung erfolgt offensichtlich bevor der String in Kleinbuchstaben gewandelt wird).

Der fertige Block, der direkt vor </config> eingesetzt wird, muss also lauten:


Damit werden Umlaute im Produktnamen im URL key korrekt umgeschrieben. Die Einstellung greift nicht für Kategorien. Wer dafür eine Lösung hat, immer her damit, aber Kategorien legt man ja auch nicht so oft neu an wie Produkte bzw. nicht in der selben Anzahl.

Steht zu euren Fehlern, Sage!

Wir benutzen für unsere Buchhaltung den GS Buchhalter von Sage. Den kann man mit diversen Datenbanksystem betreiben, unter anderem auch mit MySQL 5, was wir dankend angenommen haben, da bei uns der Betrieb mit SageDB nicht möglich war.

Jedes Jahr gibt es für den GS Buchhalter ein Update, so auch beim Jahreswechsel von 2010 nach 2011. Dieses einzuspielen wird vom Sage-Support nicht nur empfohlen, sondern regelrecht gefordert. Während das die Jahre zuvor problemlos funktioniert hat war das dieses Mal nicht so. Diverse Vorgänge liefen in einen Fehler, die Buchhaltung konnte schlicht und ergreifend nicht arbeiten. Der Anruf beim Sage-Support brachte nur die Erkenntnis, dass da ein Fehler in unserem Server für verantwortlich sein müsste, das Update selbst wäre fehlerfrei (guter Witz am Rande, aber mir war zu dem Zeitpunkt nicht nach Lachen).

Nachdem ich von der Buchhaltung eine SQL-Fehlermeldung bekommen habe war mir schnell klar, wo das Problem ist und es war auch genauso schnell klar, dass es durch das Update ausgelöst wurde:

Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation ‘=’.

Da die komplette Datenbank und alle darin enthaltenen Tabellen vom Sage-Installer (bzw. vom Updater) angelegt wurden geht die falsche Kollation ganz klar zu Lasten von Sage.
Denn die Tabelle mand hat als Kollation latin1_swedish_ci, während alle darin enthaltenen Tabellen die Kollation latin1_german1_ci haben. Naja, nicht ganz alle. Nach dem Update existierten drei Tabellen, die auch latin1_swedish_ci als Kollation nutzten: sage_auf_ratenzahlung, sage_fib_buchungstexte_termine und sage_fib_buch_split. Offensichtlich hat der Updater die Kollation dieses Mal nicht explizit angegeben und daher wird die Kollation der Datenbank benutzt. Joins, die sowohl alte Tabellen als auch diese drei mit abweichender Kollation umfassen, laufen zwangsläufig in einen Fehler.

Man kann das Problem lösen, indem man die Kollation der Tabellen händisch auf latin1_german1_ci ändert, auch die Datenbank selbst sollte man ändern, denn der nächste Sage-Updater hat eventuell genau den gleichen Bug und legt wieder Tabellen ohne explizite Kollationsangabe an.

Und was schreibt der Sage-Support, explizit auf die Punkte angesprochen?

Bei dem von Ihnen benannten Sachverhalt handelt es sich nicht um einen Programmfehler.

Nein, natürlich nicht. Und die Erde ist eine Scheibe!

Reichelt weiß, wie’s geht

Ich bestelle ja gern bei Reichelt. Nicht, weil der Shop sonderlich hübsch oder besonders gut benutzbar ist, eher das Gegenteil ist der Fall, sondern weil die Preise gut sind und die Ware schnell ausgeliefert wird.

Beim Aufräumen fiel mir jetzt ein alter Gutschein über 10 Euro in die Hände. Passend, da ich eh bestellen wollte. Geht um Strom sparen und so, mehr dazu in Kürze auf Da sich im ganzen Checkout-Prozess kein Feld findet, in das man die Gutscheinnummer eintragen könnte habe ich kurzerhand ins Kommentarfeld geschrieben, man möchte mir doch bitte den Gutschein mit der Nummer #123456 mit dieser Bestellung verrechnen.

Heute morgen finde ich dann in meinem Postfach eine E-Mail mit dem vielsagenden Betreff ‘Reichelt Mail-Service’. Und darin heißt es wörtlich:

Gutscheine benötigen wir im Original! Schicken Sie uns
diese bitte per Post (Reichelt Elektronik, Elektronikring 1,
26452 Sande) zu

Bitte beachten Sie außerdem folgendes:
– Die Ware wird erst NACH Eingang Ihrer Antwort an Sie versendet.
– Sie bekommen auf Ihre Antwort von uns KEINE Bestätigungmail.
– Wenn Sie sich auf unsere Anfrage nicht melden, wird Ihre Bestellung
nach 1 Woche automatisch aus unserem System entfernt.

Entschuldigung? Da hab ich mich wohl verhört, oder? Jedes popelige Open-Source-Shopsystem ist in der Lage, Gutscheincodes direkt im Bestellprozess entgegenzunehmen und zu validieren. Jeder Wohnzimmerversender kann folglich ein funktionierendes und für den Kunden leicht benutzbares Gutscheinsystem implementieren, nur Reichelt schafft das nicht?
Mir schon klar, warum das so ist, wenn ich mir die Gutscheinnummer so anschaue. Die ist wohl einfach fortlaufend. Aber die Lösung kann ja wohl nicht sein, dass ich mir ein Kuvert (1,99€ und neun Stück, für die ich keine Verwendung habe) und dazu eine Briefmarke (0,55€, gibt’s zum Glück einzeln) kaufen muss. Da gehen ja schon allein 25% des Gutscheinwertes für unnötige Ausgaben drauf! Darüber hinaus will das ganze eingetütet und zur Post gebracht werden. Und dann darf ich auch noch auf meine Bestellung warten, bis der Gutschein bei Reichelt eingetroffen ist und verbucht wurde!

So kann man natürlich auch die Kundschaft effektiv davon abhalten, Gutscheine einzulösen. Das Geld hat man ja schon kassiert. Ein Schelm, der böses dabei denkt.