debuggable

 
Contact Us
 

A dirty tale from the real world ...

Posted on 16/1/08 by Felix Geisendörfer

Deprecated post

The authors of this post have marked it as deprecated. This means the information displayed is most likely outdated, inaccurate, boring or a combination of all three.

Policy: We never delete deprecated posts, but they are not listed in our categories or show up in the search anymore.

Comments: You can continue to leave comments on this post, but please consult Google or our search first if you want to get an answer ; ).

Oh boy ... tonight was fun. I'm fairly busy getting PostTask.com launched (yeah, you don't need a pw for it anymore but give us a couple days before announcing public beta), and here comes the real world hitting me perfectly in the face.

A long time ago I did a little CMS for the hotel website for my step father. It was one of my first real cake apps and given that fact in retro-perspective pretty bad. I was experimenting with too many ways to use CakePHP at once and kind of ended up with a messy app. Anyway, after some weeks of occasional bug fixing it ended up working fine so I never worried much about it.

Until a couple days ago ... when the hoster updated from PHP 4.4 to 4.8 for security reasons. Don't get me wrong, I don't blame them for doing this, unfortunately this server update broke a component that this site depended upon, TextilePHP. The site uses textile for everything and the hotel suddenly was unable to update anything on it, resulting in ~5++ potential guests complaining every day about no current event schedule to be online.

I spend lots of time debugging the TextilePHP script, but I finally gave up. The thing is a 4000 line beast, full of the craziest regex, cryptic code and other goodies and multiple things where failing in it at once - not one of them I which I was able to diagnose properly (apache dying in a seg fault w/o any hint of an error sucks).

So what's the solution? Replacing the component with another one is no option - there simply isn't any compatible one out there. Removing the component? Not an option either - all contents of the site are written and stored in textile. Luckily I did decide to cache the parsed textile as an 'html' field in the db tables, so displaying old content still worked - just updating didn't. So I theoretically could have moved from textile to straight HTML - but this would have been worse then rewriting the textile parser from scratch. I would have had to be the support bitch for the client trying to input html for the rest of my life - noooooo good!

Ok, so come on people. Think Web 2.0. Think dirty. Think web services. : p ... Enough clues? If not read on.

At some point I was close to setup the old PHP version on my VPS, and move the site there. A pain in the ass, but most likely a solution that would work. Then I stopped and figured: Why move the entire site, if all you need to be moved is the Textile parser? And so thats what I did. I tried a couple of servers that I had to my disposal and finally a friend had one that ran the parser like a charm. So my evil plan turned into reality. I replaced the old TextileComponent with a new version:

// Old version:
vendor('textilephp'.DS.'Textile');
class TextileComponent extends Object{
    function toHtml($textile, $utf8 = true) {
        $Textile = @new Textile(array('flavor' => 'html/css'));
        if ($utf8==true) {
            return utf8_encode($textileClass->process(utf8_decode($textile)));
        } else {
            return $textileClass->process($textile);
        }
    }
}

// New version
uses('http_socket');
class TextileComponent extends Object{
    function toHtml($textile, $utf8 = true) {
        if ($utf8) {
            $textile = utf8_decode($textile);
        }
        $Socket =& new HttpSocket();
        $html = $Socket->post('http://secret-server/textilephp-service/', array('textile' => $textile, 'pw' => 'secret'));
        if ($utf8) {
            $html = utf8_encode($html);
        }
        return $html;
    }
}

And deployed this little script on the server of my friend:

if (!isset($_POST['pw']) || $_POST['pw'] != 'secret') {
  die('Access Denied!');
}

define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(__FILE__).DS);
require_once(ROOT.'textilephp'.DS.'Textile.php');

$post = isset($_POST['textile'])
  ? $_POST['textile']
  : "h1. Error: Param not set!\r\n\r\n";

$Textile = @new Textile(array('flavor' => 'html/css'));
echo @$Textile->process($post);

The site is now up and running again and I can focus on work thats actually fun again. But what can we learn from this post?

  • Trusting some random 4k snippet of OS maintained by a single person that produces PHP warnings / notices is a bad idea
  • Doing business with friends & family is a bad idea - they'll be able to track you down ; p
  • This is a ugly hack - don't try this at home!
  • If you build your apps properly, you'll easily be able to later outsource tasks, if necessary even to 3rd party web services
  • A weblog can be used to deal with the feeling of guilt

Sorry if you where expecting something actually useful, but I just had to post this to be able to sleep tonight ; ).

-- Felix Geisendörfer aka the_undefined

 
&nsbp;

You can skip to the end and add a comment.

derelm  said on Jan 16, 2008:

there are lots of textile implementations (for other languages) out there, so i'd probably just run an external script (e.g. python) that handles the textile to html conversion. but that's just my 2cents

Felix Geisendörfer said on Jan 16, 2008:

derelm: Well, I'm willing to bet money that non of them is 100% compatible with TextilePHP b/c it adds some custom extensions to Textile. Also the site is hosted on a shared hosting account which is why I had no control over the PHP update and certainly can't install sth like python ; ).

Matt said on Jan 16, 2008:

Wow, that's a terrible story!

I'm glad a you found a smart and dirty way to solve it!

Dieter_be said on Jan 16, 2008:

quote: "Trusting some random 4k snippet of OS maintained by a single person that produces PHP warnings / notices is a bad idea"

I understand your "list of lessons learned" isn't supposed to be taken literally but still ... you can have issues like these with any 3rd party code that you use, even stuff that is well known & well maintained

Felix Geisendörfer said on Jan 16, 2008:

Dieter_be: You can have issues with anything out there. But level of service and support vary, and if just one person maintains something its pretty low.

Take my analytics API for example, sure it wasn't bad code, but when google broke it with a new interface I didn't have time to fix it and it took me month to come up with a new (incompatible) replacement. I'm not saying you can't use something maintained by one person, I'm just saying if you don't understand the code enough to fix it in case it breaks then you're walking on thin ice ; ).

links for 2008-01-17 « Richard@Home said on Jan 17, 2008:

[...] ThinkingPHP and beyond » A dirty tale from the real world … Shows how to call a webservice from a CakePHP application (tags: cakephp webservice) [...]

Walker Hamilton said on Jan 27, 2008:

Hey Felix,

They fixed it.

* Fix textile list incompatibility with PHP 5.2.4 (and higher)

(Download the newest textpattern install: http://forum.textpattern.com/viewtopic.php?id=25795 )

Felix Geisendörfer said on Jan 28, 2008:

Hey Walker: I'm not using textpatterns textile implementation but the one I linked to above ; /

This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.