uniform

CakePHP custom error class doesn’t work when providing translations

So today I was trying to make a form that was friendly between CakePHP and UniForm. Things were going really well, I created a standard options array which converted the markup into UniForm friendly markup, it all looked good until I went to submit. Cake was somehow forgetting the error class I specified. Let’s get to some examples…

The Model Validation Rules

<?php
class Product extends AppModel {
 
	var $name = 'Product';
 
	var $validate = array(
	    'title' => array(
    		'notEmpty' => array(
    			'rule' => 'notEmpty'
    		),
	    )
	);
}
?>

The View Template

<div class="products form">
<?php echo $form->create('Product', array('type' => 'file'));?>
	<fieldset>
 		<legend><?php __('Add Product');?></legend>
	<?php
		$options = array(
			'error' => array(
				'class' => 'errorField',
				'email' => 'Please enter a product title'
			)
		);
		echo $form->input('title', $options);
		echo $this->element('attachments', array('plugin' => 'media'))
	?>
	</fieldset>
<?php echo $form->end('Submit');?>
</div>
<div class="actions">
	<ul>
		<li><?php echo $html->link(__('List Products', true), array('action' => 'index'));?></li>
	</ul>
</div>

Which, when submitting the form with an empty product title would you give the error message of “Please enter a product title” inside a div with the class “errorField”, however Cake forgets the custom error class and gives the “error-message” class.

What Happened?

I got this code…

<div class="input text error">
    <label for="ProductTitle">Title</label>
    <input type="text" class="form-error" id="ProductTitle" value="" maxlength="255" name="data[Product][title]"/>
    <div class="error-message">Please enter a product title</div>
</div>

What was expected?

This…

<div class="input text error">
    <label for="ProductTitle">Title</label>
    <input type="text" class="form-error" id="ProductTitle" value="" maxlength="255" name="data[Product][title]"/>
    <div class="errorField">Please enter a product title</div>
</div>

The Fix

After looking through the core code, I traced the problem down into the error function of the FormHelper. The input() function only passes the $field name and the $text variable as the options submitted in the original “error” key to the options passed to the input() function.

In the error function, if the $text array contains the key of the error type, then it disregards the rest of the $text array, forgetting the custom error class. What we need to do is set the $options variable to $text if it is in array, as well as pull the custom message for the error type, kapeech? OK, I’ll just give you the code…

Before

411
412
413
414
415
416
if (is_array($text) && isset($text[$error])) {
	$text = $text[$error];
} elseif (is_array($text)) {
	$options = array_merge($options, $text);
	$text = null;
}

After

411
412
413
414
if (is_array($text)) {
	$options = array_merge($options, $text);
	$text = isset($text[$error]) ? $text[$error] : null;
}

I never like touching core code so I’m hoking the cake devs will be able to get on this for the next release, and it looks like I just missed the next release, as CakePHP 1.2.5 just popped up on my reader.

I have submitted a ticket at http://code.cakephp.org/tickets/view/76

Without Surgery

Without Surgery is the biggest showcase of the open source tools I have released. It uses Advindex to manage, import and export the contact enquiries, competition entries, clinics and voucher purchases. Uniform is the engine used to generate all the forms. Baked Simple manages the content across the site (which in turn uses EAV). Reports generates the statistics used to monitor competition entries and voucher purchases. Settings is used for misc settings such as where the contact form will be sent to. Payments is used to execute the transactions to purchase vouchers. The Campaign Monitor behavior attaches itself to contact enquiries, competition entries, voucher purchases and subscriptions so synchronise the database on both systems. And finally Store Finder locates the nearest retailer, which is seamlessly integrated when purchasing a voucher.

To top it off I wrote the functional specifications and it also integrates with a forum platform called Vanilla.

http://www.withoutsurgery.com.au