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

One Comment

  1. Craig
    Posted September 12, 2009 at 4:58 pm | Permalink

    Good work!

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">