PS: And if you want to run Firebug in your 10 new browsers you can bookmark the Firebug Lite bookmarklet and you get almost the same featureset as the native firefox extension gives you!
| [ 0 trackbacks ] | permalink | related link |




( 3 / 179 )OK here's one that might save you some time. I have a symfony admin gen site that works fine in all browsers but for some reason the rich calendar inputs failed to appear in IE7.
At first I thought this might have been the reason:
http://forum.symfony-project.org/index.php/m/58074/
But my calendar.js was already patched!
It turns out that you have an object in the DOM with an ID of "content" then you might find that any Dynarch calendars appear off-screen in IE7 only!
Rename your element to something else and it starts working. Don't ask me why, I can't find any reference to 'content' in the calendar script files. It's just one of those quiry things that makes you even more convinced that hating IE7 is completely justifiable!
| [ 0 trackbacks ] | permalink | related link |




( 3 / 175 )It's still very early days, but Symfony 2 now has it's own site with some introductory material included. You can get the code and read about the framework - although there's no side-by-side comparison with symfony 1.4.
Now that versions 1.0, 1.1 and 1.2 are all officially dead (and 1.3 being a transitional version from 1.2) it looks like 1.4 will be the last stepping stone before 2.0.
And what's so different about sf2? Well for starters it looks like every component of the symfony framework has been decoupled into what they are calling "bundles". Hmm, that sounds a bit like Zend doesn't it? Interestingly, the Zend framework is one of the core symfony 2 bundles! Whoop! I guess that means you could use the Zend MVC in place of the Symfony one, hypothetically...
Additionally, your app is a bundle, too - although I can't think of any real expedient here as I doubt your app will be of much use without the other bundles. Perhaps this allows you to easily unplug it from synfony 2 and move it somewhere else... in a parallel universe perhaps.
Ironically, the sf2 site also publishes some "hello world" benchmarks which, while impressive, are still subject to the criticisms thrown at earlier benchmark results where symfony did not do so well - hello world is not an application where a framework is useful etc. Anyway here are the stats:
For the "Hello World" application, the Symfony 2.0 is about:
* 20% faster than Solar 1.0.0beta3
* 60% faster than Lithium 0.6
* 75% faster than Yii 1.1.1
* 2 times faster than symfony 1.4.2
* 3.5 times faster than Zend 1.10
* 5.5 times faster than CakePHP 1.2.6
* 69 times faster than Flow3 1.0.0alpha7
Anyway, it doesn't look to me like symfony is getting easier, but it is definately getting better. I am particularly looking forward to the new debug toolbar:
| [ 0 trackbacks ] | permalink | related link |




( 3 / 159 )Do you use water cooling? Well my advice is put a calendar item to check it monthly. And run a CPU temp app at all times. You see today after 3 years of smooth sailing my reservoir ran dry, cooked my cpu and then (after I quickly refilled it) sprayed water all over the motherboard, video card and power board, killing everything and short-circuiting the entire house.
Woohoo!
| [ 0 trackbacks ] | permalink | related link |




( 2.9 / 184 )Had this strange problem ever since we upgraded a Symfony site from 1.0 to 1.2 - the emails being logged to the database were being mangled.
The problem turns out to be simply that the symfony 1.2 swToolkit plugin uses Zend Mail instead of phpMailer and Zend Mail spits out encoded text when you ask it for the email text or HTML contents.
So the simple fix is to wrap the data you get out of Zend Mail with the obscure quoted_printable_decode() function as shown here:
$message = quoted_printable_decode($zendEmail->getBodyHtml()->getContent());
$text = quoted_printable_decode($zendEmail->getBodyText()->getContent());
There, that gets rid of all those =0D=0A characters everywhere!
Note that you would think you could avoid this simply by passing the line ending explicitly, but it does not work:
//this does *NOT* work!
$message = $zendEmail->getBodyHtml()->getContent("\r\n");
$text = $zendEmail->getBodyText()->getContent("\r\n");
| [ 0 trackbacks ] | permalink | related link |




( 3 / 209 )All right now Google are installing Chrome inside Internet Explorer so now Microsoft can claim to have a standards compliant browser. But what I'm excited about is viewing it all inside Firefox with the ieTab plugin!
That's Firefox rendering Internet Explorer rendering Chrome.
Now somebody create a chrome plugin that uses the Opera rendering engine or - even better - the Firefox rendering engine!
Whoop!
| [ 0 trackbacks ] | permalink | related link |




( 3 / 208 )This is something that has been discussed in the Symfony google groups but was unresolved - how to modify a view configuration based on the environment. Some developers say you should not be doing this, as the view should be the same in all environments, but let me explain why I needed do do it...
I have some javascripts loaded from google to speed up my sites - anyone who has used the Yahoo YSlow plugin for FireBug will be familiar with the "F" rating for content delivery networks (CDN) score. But I have a developer on my team who works offline and wants to be able to develop locally without having to constantly modify all the view.yml files (and there are a few!) for each app.
So, although it would be nice to be able to specify an environment in the view.yml the same way you can in the settings.yml, some folks forget that you can put PHP code in your view.yml to be evaluated at runtime (or at least read from the cache at runtime!).
So, this is how we manage to serve google's minified high speed Javascript libraries in the "live" environment but use local copies elsewhere:
default:
javascripts:
- <?php echo (strpos(SF_ENVIRONMENT,"live")!==false?'http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js':'/js/prototype').PHP_EOL ?>
- <?php echo (strpos(SF_ENVIRONMENT,"live")!==false?'http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.2/scriptaculous.js?load=effects':'/js/scriptaculous/scriptaculous.js?load=effects').PHP_EOL ?>
Damn, that was easy, wasn't it?
:-)
| [ 0 trackbacks ] | permalink | related link |




( 3.1 / 176 )Well, in case you were wondering, I managed to get around my scalability problem by focussing on PHP's strengths and side-stepping it's weaknesses. So in this particular problem I was facing 2 primary bottlenecks - yaml parsing and propel memory leaks.
I got around the yaml issue by using some custom string hacking - and PHP's string functions are pretty quick. By using split() and strpos() I could slice up my big yaml file into more digestible sizes (see previous post).
The propel issue, however, was always going to be more problematic. I considered removing all my ORM calls and either using delayed inserts or LOAD DATA INFILE statements. Both of which I have used successfully in the past, but implementing it in this case meant a complete rewrite of over 2000 lines of tested code.
So, I decided to use a similar approach to the ORM. Like YAML, Propel 1.2 is very good at what it does inside small to medium processes. It just isn't very efficient when used in big jobs - like inside large loops. So instead of trying to process my massive array that I managed to construct from the original yaml, I sliced it up and sent smaller yaml files back into the queue.
What this means is that instead of having a single item of 13,000 recipients sitting in the queue I have 130 items of 100 instead. My queue processing task can now batch 100 emails at a time and then terminate, thereby freeing up memory for the next batch. While there is some extra overhead in writing files to disk and duplicating some of the yaml, the benefits are well worth it. The end result is a scalable, fast and robust system that can handle almost any request by simply slicing it up into manageable chunks. TIme and money saved, client happy :)
| [ 0 trackbacks ] | permalink | related link |




( 3.1 / 179 )This is a problem I often come up against - sending email to thousands of recipients. The way I usually handle it is to do as little as possible in the master loop.
The best technique I have found is to defer database writes by writing to a temporary textfile in memory (using php://memory) and then using LOAD DATA INFILE to write contents to the database. That puts all the email data into a database queue, allowing a cron task to send the emails - say 50 per minute.
Using this technique I can send 50,000+ emails quite easily. The queue function takes under a minute to run and the cron job hacks away at the queue for about 24 hours or so.
The problem I have with this technique is that it evolved via a process of whittling away at the various framework layers used in my "enterprise applications". Framework layers supposedly designed to provide scalability.
Now you can probably tell from this blog that I use Symfony extensively (although I have dabbled with other frameworks, I always come back to Symfony). Perhaps it is due to the fact that my largest projects (over 1,000,000 lines of code) are locked into Symfony 1.0 and - more importantly - Propel 1.2. Arguably, what I should be doing is writing a Symfony plugin that performs large data processing using the techniques I've described, but it seems a shame to have a detailed, documented and unit-tested ORM that can only be used for serving small jobs like "web pages", and must be bypassed for any data intensive stuff. Isn't that a core requirement of "enterprise level" scalability?
Anyway, I'll try to end the rant with some code. Last night I wrote a custom yaml parser because the sfYaml::load() method in Symfony 1.0 (which uses spyc) was taking over 20 minutes to load a 1MB yaml file. I managed to load it in about 5 seconds. Now, I'll admit it's not really a yaml parser but more of a key-pair extractor but because it doesn't use any regex it is waay faster than the old sfYaml.
(NB: I couldn't install syck on my CentOS4 server and the newer sfYaml component from 1.2 failed to load yaml collections in the format shown below).
The yaml (multiply this by 10,000):
Recipients:
- title: 'Mr'
firstname: 'Bob'
lastname: 'Dobbs'
company: 'Subgenius Network'
email: 'bob@subgenius.com'
- title: 'Mrs'
firstname: 'Jane'
lastname: 'Dobbs'
company: 'Subgenius Network'
email: 'jane@subgenius.com'
The recipient extractor method:
public static function extractRecipients($yaml)
{
//separate recipients from yaml
$recipients_string = "Recipients:";
$recipients_start = strpos($yaml,$recipients_string);
$recipients_end = strpos($yaml,"bcc:");
$recipients_yaml = substr($yaml,$recipients_start,
($recipients_end-$recipients_start));
$yaml_start = substr($yaml,0,$recipients_start);
$yaml_end = substr($yaml,$recipients_end);
$yaml = $yaml_start . $yaml_end;
//load yaml
$yaml_array = sfYaml::load($yaml);
//get recipients array
$recipients_yaml = str_replace($recipients_string,"",
$recipients_yaml);
$recipients_array = split("-",$recipients_yaml);
//loop over recipients to get getails as array
$recipients_list = array();
foreach ($recipients_array as $r1) {
//loop over each line item
$r1_array = split("\r\n",$r1);
$my_recipient = array();
foreach ($r1_array as $r2) {
if (strpos($r2,":")!==false){
//extract key pair from line item
$r2_array = split(":",$r2);
if (sizeof($r2_array) == 2){
$key = str_replace("''","'",
trim(trim($r2_array[0]),"'"));
$value = str_replace("''","'",
trim(trim($r2_array[1]),"'"));
$my_recipient[$key] = $value;
}
}
}
if (sizeof($my_recipient) > 1){
//add this recipient to list
$recipients_list[] = $my_recipient;
}
}
//add recipients to yaml data
$yaml_array[trim($recipients_string,":")] = $recipients_list;
//return yaml data
return $yaml_array;
}
| [ 0 trackbacks ] | permalink | related link |




( 3 / 174 )I have enabled comments on the blog after a few requests for it... play nice!
| [ 0 trackbacks ] | permalink | related link |




( 3 / 162 )Back Next



Avatar



