Skip to first unread message

Mark Rickerby

Aug 27, 2008, 9:54:52 PM8/27/08
to SilverStripe Development
Flying home from the Silverstripe AK web meetup, I wondered, was there
anything that I missed? I asked the pilot of the ROFLCOPTER, who
seemed like a wizened old veteran, surely he would know.

Exhibit 1. b) The ROFLCOPTER

______ / \______
L / \
LOL====== \__
L \__________________]

The pilot began to tell me a tale of high drama, love, and betrayal,
worthy of Shakespeare, but as captivated as I was, I started to feel
like something was wrong. When he got to the part about the furries, I
KNEW something was wrong. Clearly, this pilot was not going to help me
solve my existential crisis, but once he got started, there was just
no way to shut him up except to bring down the ROFLCOPTER itself. He
seemed to be building up to something - the moment of truth, when he
would reveal his true "fursonality" to me. The look in his eyes was
terrifying, and I had no choice but to grab a parachute and dive

Exhibit 1. b) A Furry
. .
/ \ / \
/ ) `---' ( \
/ \
/ /o o\ \
/ / \ \
' \___/ '
\ > '.' < /
\ '---'---' /
> <

I crashed unceremoniously through a tangle of tree branches which
ripped my parachute to shreds, and tumbled onto the ground, nearly
smashing into a bum who was stumbling along, muttering and mumbling to
himself. As I slowly got to my feet, I looked up and saw that the bum
was staring intently at me, holding a brown paper bag with a bottle of
what looked like red wine. As he got closer, I started to discern that
he was actually muttering the same thing over and over again.

"Flush cache all. Flush cache all. Flush cache all. Flush cache all.
Flush cache all. Flush cache all..."

I tried to ask him what was wrong, and he began to tell a chilling
story in broken, halting English. The bum was once king of all these
lands, a wise and just ruler. But his army was eventually overthrown
by an invading dictator, and the great city in the forest stood in
ruins. "For want of a template, the kingdom was lost." When I asked
him what this meant, he just pointed to a rusted and trashed shopping
cart with the letters "P H P" scratched into the metal, and continued
to mutter.

As I tried to figure out what "Flush cache all" meant, I felt
something tugging at my trouser leg. I looked down and saw the beady
little eyes of a Leprechaun staring up at me.

" 'tink of the LOLCACHE, my boy", he said, and scuttled off into the

At last. A clue!

I started to explore the forest, looking for the mythical LOLCACHE.
Hours later, it was dark, and I was tired, sore and hungry, from my
journey, but there was still no sign of the LOLCACHE. Suddenly, I
stumbled into a clearing with an old broken down well in the center.
The sight filled me with hope - I knew there had to be an answer here.
But looking down the wellshaft, I jumped back in absolute horror. The
sight I saw was too NSFW to put into words. I cringed, and almost
vomited over my shoes.

Exhibit 1. c) The Goatse of template engines

$content = ereg_replace('<!-- +pc +([A-Za-z0-9_(),]+)
+-->', '<' .
'% control \\1 %' . '>', $content);
$content = ereg_replace('<!-- +pc_end +-->', '<' . '%
end_control %'
. '>', $content);

$content = ereg_replace('<' . '% +control +([A-Za-z0-9_]
+) +%' .
'>', '<? array_push($itemStack, $item); if($loop = $item->obj("\\1"))
foreach($loop as $key => $item) { ?>', $content);
$content = ereg_replace('<' . '% +control
+([A-Za-z0-9_]+)\\.([A-Za-z0-9_]+) +%' . '>', '<?
array_push($itemStack, $item); if(($loop = $item->obj("\\1")) &&
($loop = $loop->obj("\\2"))) foreach($loop as $key => $item) { ?>',

$content = ereg_replace('<' . '% +control
+([A-Za-z0-9_]+)\\.([A-Za-z0-9_]+)\\(([A-Za-z0-9_-]+)\\) +%' . '>',
'<? array_push($itemStack, $item); if(($loop = $item->obj("\\1")) &&
($loop = $loop->obj("\\2", array("\\3")))) foreach($loop as $key =>
$item) { ?>', $content);

$content = ereg_replace('<' . '% +control
+([A-Za-z0-9_]+)\\(([A-Za-z0-9_-]+)\\) +%' . '>', '<?
array_push($itemStack, $item); if($loop = $item->obj("\\1",
array("\\2"))) foreach($loop as $key => $item) { ?>', $content);
$content = ereg_replace('<' . '% +control
+([A-Za-z0-9_]+)\\(([A-Za-z0-9_-]+), *([A-Za-z0-9_-]+)\\) +%' . '>',
'<? array_push($itemStack, $item); if($loop = $item->obj("\\1",
array("\\2","\\3"))) foreach($loop as $key => $item) { ?>', $content);
$content = ereg_replace('<' . '% +control
+([A-Za-z0-9_]+)\\(([A-Za-z0-9_-]+), *([A-Za-z0-9_-]+),
*([A-Za-z0-9_-]+)\\) +%' . '>', '<? array_push($itemStack, $item);
if($loop = $item->obj("\\1", array("\\2", "\\3", "\\4")))
foreach($loop as $key => $item) { ?>', $content);
$content = ereg_replace('<' . '% +end_control +%' .
'>', '<? } $item
= array_pop($itemStack); ?>', $content);
$content = ereg_replace('<' . '% +debug +%' . '>', '<?
Debug::show($item) ?>', $content);
$content = ereg_replace('<' . '% +debug +([A-Za-z0-9_]
+) +%' . '>',
'<? Debug::show($item->cachedCall("\\1")) ?>', $content);

But I was so close to discovering the source of the LOLCACHE! After
steeling myself against the evil powers of the regex, I began to climb
down a rope ladder that was conveniently slung down the well - almost
like somebody knew I was coming.

And as I got to the bottom, I knew. There it was, staring up at me!
The LOLCACHE itself!

Remembering back to my beloved tutor Macgyver, I wondered "what would
HE do?". The answer was obvious. I jury rigged a system that would
harness the LOLCACHE for good, and provide the power to flush it at

Exhibit 1. d) Flushing the LOLCACHE

static function flushTemplateCache() {
$dir = dir(TEMP_FOLDER);
while (false !== ($file = $dir->read())) {
if (strstr($file, '.cache'))

I had it in my grasp, now all I had to do was figure out how to pull
the trigger on this bad-boy. I climbed out of the well, and noticed a
strange presence in the air, a tingling, buzzing feeling, and a faint
odor of ozone. Suddenly, I heard a rumbling thunder above me, and
looked up to see a tractor beam scanning through the forest. I tried
to dive out of the way, but the beam was so fast, I could not resist
its incredible energy and felt myself being sucked up into the air.

As I floated up the beam, I started to get a better view of its source
- a gigantic spaceship. As I got closer, I noticed that there was a
logo emblazoned on the outside - and suddenly realized this was the
infamous GeoffCorp Orbiting Command Post. Soon I was face to face with
the self styled lord of GeoffCorp himself.

"I wouldn't touch that LOLCACHE if I was you.". He cackled, and
launched into a lengthy monologue regarding the fine details and
quality of different types of knife and the virtues of red wine. Using
the wine meme as cover, I sneaked over to one of the many console
terminals on the command post, and began to plan my escape.

After minutes of furious grepping, I looked up to see that a giant
video screen was humming to life. Darth Munn was beginning a
conversation with none other than the Sith Lord Cartman! A chill ran
up my spine.

Cartman and Darth Munn were plotting to sweep over the whole land with
an army of LOLERSKATERS that they had engineered by parsing ASCII
characters out of the BSD license! I thought of the great freedom
crusader Stallman and wondered "what would HE do?".

Exhibit 1. e) A LOLERSKATER

/ \ 0
/ \ _/
/ \
/ \

There was only one thing for it. I had to patch the LOLCACHE for

Wildly scanning through lines and lines of terminal output, I kept one
ear on the conversation over the giant video screen. Darth Munn was
reciting an epigram on the virtues of an antiquated and thoroughly
nefarious piece of technology called POSTDIZZZQL. This terrified me
even more, and I continued my search with more intensity.

Eventually, I realized I was barking up the wrong tree... I could just
ride on the back of the existing ?flush=elephant. There was no
elaborate solution, just a quick hack that might ultimately save the

Exhibit 1. f) The mighty ?flush=all hack in sapphire/main.php

// Flush the template cache if requested
if (isset($_GET['flush']) && $_GET['flush'] = 'all') {

No sooner had I fired this code into the midst of the SSViewer
machinery, when I heard an almighty scream. I had wiped out the
LOLCACHE that the LOLERSKATER army of doom were going to use to sweep
through the land. Less than 10 lines of code, and I had saved the
forest and the whole world! Now I just had to escape from the Orbiting
Command Center.

"Easier said than done", mocked Darth Munn. I looked up to see the
ominous face of his personal bodyguard Jack Hammer chomping on a cigar

"I didn't even say that out loud", I cried, running towards the
nearest airlock, and diving through the doors to the escape pod.

"You'll never get away with this", they screamed.

"It's too late!" I yelled. "I've already deployed it to one site, and
there's more on their way"...

As the escape pod rocketed away from the Orbiting Command Center, and
I began to feel the slamming g-forces of re-entry, I wondered what
adventures would befall me when I landed.

The End.

Matt Peel

Aug 27, 2008, 10:56:32 PM8/27/08
This is by far the best post to this mailing list. Ever. You win some
form of prize, which you can collect from Darth Munn the next time you
see him.


Sam Minnee

Aug 27, 2008, 11:00:26 PM8/27/08
to SilverStripe Development
And the award for most entertaining patch ever goes to Mark
Rickerby ;-)

"The goatse of template engines" - Hrmphf! :-P

On a more serious note... It would probably make more sense to call
SSViewer::flushTemplateCache() from within SSViewer, just before the
cache is inspected to see if we need to compile a template or not.
That'll keep it more encapsulated.

Can you wrap that into an actual changeset? :-) Seems like a good
candidate for trunk to me.

Mark Rickerby

Aug 27, 2008, 11:24:36 PM8/27/08
to SilverStripe Development
Blame Geoff and Craig's little exchange last night for that one... and
the fact that I was on an excruciatingly boring bus ride home and
needed some entertainment. Since I keep hearing over and over again
"why isn't there a flush all for templates?", I thought why not just
take it waaaay too far...


I should be able to wrap all that inside SSViewer and push it thru.
Probably make it a private method then, if that's the case.

Sam Minnee

Aug 27, 2008, 11:35:00 PM8/27/08
to SilverStripe Development
Yep, agreed.

The only final thing that you might want to consider is whether we
should have some kind of class responsible for managing the access to
all those random developer querystring variables... But that's a bit
of a bigger question.

Mark Rickerby

Aug 28, 2008, 12:10:42 AM8/28/08
> The only final thing that you might want to consider is whether we
> should have some kind of class responsible for managing the access to
> all those random developer querystring variables...

It's a good idea, but there are a lot of places where they appear, it
might not be a straightforward task. I wonder if the debug class could
be used as a way to wrap some of the vars, but that still leaves a
fair bit of code in SSViewer that switches on GET params.


Aug 28, 2008, 5:23:38 AM8/28/08
to SilverStripe Development

I almost roflcoptered myself out of my chair. Everyone needs a ?
flush=elephant. bbqhax.


> I began to feel the slamming g-forces of re-entry, I ...
> read more »
Reply all
Reply to author
0 new messages