Acronyms, acronyms, acronyms

"Engineers are really good at labeling and branding things," said his sarcasm. "If we had named Kentucky Fried Chicken, it would have been Hot Dead Birds." - Vint Cerf

So long KarmaSphere

After quite some time serving the world, KarmaSphere's reputation lists are ending. If you're running KarmaSphere on your mail server(s), now would be the time to start thinking about removing that as an anti-spam feature.

To the KarmaSphere team, I wish you well with your new endeavors, and I hope that you continue to come up with innovative products!

Zend_Form, default decorators and fieldsets

Another less-sysadmin-y, more code-y post today.

Zend_Form is pretty handy, and takes care of a lot of the hard work in producing and validating forms. Unfortunately the default decorators aren't quite as sane in my opinion, which becomes obvious if you start using fieldsets, or display groups, as ZF refers to them - You'll see your fieldsets getting wrapped in an additional definition list which is basically crap if you ask me. You can get rid of them with CSS, but its tricky.

To avoid this, until today I've been using a set of custom decorators and getting increasing frustrated in having to add more and more to support ZendX_JQuery_Element's and Zend_Form_Element_File, etc. Feeling somewhat defeated as I was hitting the limits of the decorators documentation, I started taking another look at the default decorators and what could be done with the minimal amount of tedious work, in terms of drop in replacements and slight CSS alteration. I came up with a reasonably good solution that I cannot believe I didn't see before.

I've plonked the code below (sanitized from anything specific to my setup - such as HTMLPurifier integration, etc. - with a test form to help you see how it works) incase anyone happens to be interested. Given the unusual increase in commenting I've been getting against using Zend Framework and the PHP Sqlsrv extension I figured it might be worth posting (I'm sure I'm not the only person out there who has missed the obvious).

What I've basically done is tell the form to render form elements, wrapped in a form. Display groups should then only display the elements, wrapped in a dl, wrapped in the fieldset. I've added some "plain" fieldsets which I use for control elements, such as submit or reset buttons. I've also given these items classes which allows me to remove the fieldset through styling, and move the positioning easily.
class My_Form extends Zend_Form { // Form protected $_formDecorator = array('FormElements', 'Form'); // Display Groups protected $_groupDecoratorStd = array('FormElements', array('HtmlTag', array('tag'=> 'dl')), 'Fieldset'); protected $_groupDecoratorCtl = array('FormElements', 'Fieldset'); // Ctls and hidden elements protected $_elementDecoratorCtl = array('ViewHelper'); public function __construct($options = null) { parent::__construct($options); // Add our HTMLPurifier filter(s) $this->addElementPrefixPath('My_Filter', 'my/Filter/', 'filter'); // Add our Confirmation validator $this->addElementPrefixPath('My_Validate', 'my/Validate/', 'validate'); // Add our custom elements path $this->addPrefixPath('My_Form_Element', 'my/Form/Element/', Zend_Form::ELEMENT); $this->setAttrib('accept-charset', 'UTF-8'); $this->setMethod('post'); $this->setDecorators($this->_formDecorator); $this->setDisplayGroupDecorators($this->_groupDecoratorStd); } public function addAntiCSRF($salt, $timeout = 300, $name = 'no_csrf_foo') { $this->addElement('hash', $name, array( 'decorators' => $this->_elementDecoratorCtl, 'salt' => $salt, 'timeout' => $timeout )); } public function addSubmit($labelSubmit = 'Submit') { $this->addElement('submit', 'submit', array( 'label' => $labelSubmit, 'decorators' => $this->_elementDecoratorCtl, 'class' => 'submit' )); $this->addDisplayGroup( array('submit'), $this->getGroupName('controls'), array( 'legend' => 'Controls', 'class' => $this->getControlsClass(), 'decorators' => $this->_groupDecoratorCtl ) ); } public function addSubmitReset($labelSubmit = 'Submit', $labelReset = 'Reset') { $this->addElement('submit', 'submit', array( 'label' => $labelSubmit, 'decorators' => $this->_elementDecoratorCtl, 'class' => 'submit' )); $this->addElement('reset', 'reset', array( 'label' => $labelReset, 'decorators' => $this->_elementDecoratorCtl, 'class' => 'reset' )); $this->addDisplayGroup( array('submit', 'reset'), $this->getGroupName('controls'), array( 'legend' => 'Controls', 'class' => $this->getControlsClass(), 'decorators' => $this->_groupDecoratorCtl ) ); } protected function getGroupName($name) { return get_class($this).'-'.$name; } protected function getControlsClass() { return array('controls', get_class($this).'-controls'); } protected function getInputsClass() { return array('controls', get_class($this).'-inputs'); } } class Test_Form extends My_Form { public function init() { $this->addElement('text', 'title', array( 'label' => 'Title', 'validators' => array( array('StringLength', false, array(2,50)) ), )); $this->addElement('file', 'file', array( 'label' => 'file', )); $elem = new ZendX_JQuery_Form_Element_DatePicker( 'dp', array( "label" => "Date Picker", 'validators' => array('Date'), 'required' => true ) ); $this->addElement($elem); $this->addElement( 'hidden', 'shush', array( 'value' => 'its quiet', 'decorators' => $this->_elementDecoratorCtl ) ); $this->addElement('text', 'comments', array( 'label' => 'Comments', 'validators' => array( array('StringLength', false, array(2,50)) ), )); $this->addDisplayGroup( array('title', 'file', 'dp', 'comments'), 'inputs', array( 'legend' => 'INputs' ) ); $this->addSubmitReset(); } }
Granted there are other solutions, but this works rather well for what I needed - a drop in replacement and the (valid) HTML structure that I wanted.

You should probably want to alter this if you're starting without any legacy stuff hanging over your head.

It should be noted this was written against Zend Framework 1.9.2, there's no guarantee that this will still be valid against future versions or older versions (although it's pretty likely and I've been using Zend_Form with few changes since early 1.x).

SSD love

That's right, I've got the SSD love.

Earlier this week a Crucial CT64M225 arrived. My initial surprise was of how light it was. Obviously it wasn't going to be heavy, but after years of playing with 2.5" drives in laptops and more recently servers, I was expecting a bit more weight to the thing. Chris convinced me to pop it in over lunch, which I did with great results: An average read speed of 224.8MB/s, a burst speed of 189MB/s, with a random access time of 0.1ms. In comparison to my fake RAID 0 (2x500GB Samsung Spinpoints at 7200rpm) running at an average read speed of 153.3.8MB/s, a burst speed of 307.4MB/s, with a random access time of 12.7ms (which isn't exactly that slow either tbh).

I've retained my RAID array for data, but the OS is entirely on the SSD. If you're thinking about a new build. this is almost certainly the way you want to go within the next 6-12 months. I can certainly see the benefits of SSDs in a small database servers, although server grade stuff is still fairly expensive and only available from a few vendors out of the box.

I'd love to get another, but the only thing preventing me is the price. I'd absolutely love to have a second in here to use as play device for Linux or OpenSolaris as a quick-boot OS for anything but games or work, but at £120-ish for 64GB, it's a little on the prohibitive side. Of course, I could use the old Windows partition on the RAID 0, however after being stung by launchpad bug #380138/#219393 last time I did a rebuild, I'm not sure I have the patience to keep with the seeming ever changing outcome of a "libata: kernel options vs /etc/modprobe.d" argument.

Zend Framework and the PHP Sqlsrv extension

On the off chance you're intending to do any development with using SqlSrv and ZF, I'd suggest taking a cursory look at ZF-7431 before hand. Equally if you're planning on doing any dev with Sqlsrv and plan to migrate to other SQL platforms later, then it could be just as helpful.

The fact that SqlSrv will return PHP objects is rather nice, unless you already have existing code that assumes strings are returned, like almost all other database extensions available for PHP. The easiest "fix" to allow your code to work across as many systems as possible is to ensure that you pass in ReturnDatesAsStrings as an option.