Can't change default error messages in CakePHP 2.3 - error-handling

In my CakePHP project, I want to display error messages but it's not working.
When I'm submitting, I want it to display an error message like: "This field is required", but by default it's showing "Please fill out this field". I changed the message, but it's not changing from the core.
My View, Model, and Controller codes are as following:
add_district.ctp:
<div class="pg_title txtLeft">Add District</div>
<?php echo $this->Form->create('Admins', array('action' => 'add_district'));?>
<table>
<tbody>
<tr>
<td><label>District Name<span class="red required">*</span></label></td>
<td><?php echo $this->Form->input('District.district_name',array('label'=>false,'div'=>false,'size'=>50,'style'=>'width:330px;')); ?></td>
</tr>
<tr>
<td colspan="2" align="right" style="padding-right: 113px;"><input type="reset" value="Reset"> | <?php echo $this->Form->submit('ADD', array('div' => false));?></td>
</tr>
</tbody>
</table>
<?php print $this->Form->end();?>
<div class="clear"></div>
Model : District.php
<?php
App::uses('AppModel', 'Model');
/**
* Admin Login Model
*
*/
class District extends AppModel
{
public $name='District';
public $usetables='districts';
public $validate = array(
'district_name' => array(
'rule' => 'notEmpty',
'allowEmpty' => false,
'message' => 'This field is required'));
}
?>
And my controller Code is (AdminController.php):
public function add_district()
{
$this->layout='common';
$this->District->create();
$this->District->set($this->data);
if(empty($this->data) == false)
{
if($this->District->save($this->data))
{
$this->Session->setFlash('District Added Successfully.');
$this->redirect('add_district');
}
}
else
{
$this->set('errors', $this->District->invalidFields());
}
}

That message "Please fill out this field" is from the browser itself, not from CakePHP.
So Firefox and Chrome (and possibly other browsers?) automatically check for fields marked as required, and then when you submit a form, before even sending that form data to the server, if a required field is not filled in, the browser will give you that default popup message: "Please fill out this field".
This is the browsers default behaviour, and has nothing to do with your code. If you'd like to check that your Cake error message is working OK, then try in Safari (which, as of version 6.0.2, doesn't seem to have that 'auto detect required fields' feature). In Safari, you should get your own CakePHP error message back.
You can also prevent error checking in the browser by passing the autovalidate attribute as false for the form itself - see Disable validation of HTML5 form elements

Actually CakePHP is triggering this by adding the HTML5 required="required" attribute via the FormHelper. Previous versions of CakePHP did not do this. You can prevent this by adding 'required' => false to your form input atributes array if you wish.

The problem is the browser validation.
On Chrome, at least, if input fields have been set to 'required' you are going to be frustrated. It seems to work without a problem on Safari.
Even if you add 'required'=>false from the Model, it still might not work.
What I did to get it working was on the View, I added 'required'=>'false'
e.g. I have a Users View and an add.ctp
echo $this->Form->input('fname', array('label' => 'First Name','required'=>'false'));
after that it all worked out. but I had to do it on all input fields for the cake validation to work.

In add_district.ctp write
<?php echo $this->Form->create('Admins', array('action' => 'add_district', 'novalidate' => true));?>
I think this will solve your problem.

Related

yii custom error pages like 404, 403, 500

I'm trying to have separate files for all my error messages. (404, 403, 500 etc) so i can have custom designs for them. If possible i don't want the header and footer to be included in my error pages too. Right now i have this, in my SiteController.php and put error404.php into my views/site/ folder
public function actionError()
{
$error = Yii::app()->errorHandler->error;
switch($error['code'])
{
case 404:
$this->render('error404', array('error' => $error));
break;
.......
.......
}
}
i was wondering if there is a better way? or if Yii has way to handle this that i'm missing.
i read this page http://www.yiiframework.com/doc/guide/1.1/en/topics.error
and it says something about putting files into /protected/views/system but i don't quite understand Yii's documentation.
As you read Yii will look for files in /protected/views/system (after looking in themes if you have any)
You do not need to write any fresh actions all you have to do is create a folder system in the views directory and create files named errorXXX.php XXX being the error code.
The default page looks like this you modify this as you wish and save it in /protected/views/system
<body>
<h1>Error <?php echo $data['code']; ?></h1>
<h2><?php echo nl2br(CHtml::encode($data['message'])); ?></h2>
<p>
The above error occurred when the Web server was processing your request.
</p>
<p>
If you think this is a server error, please contact <?php echo $data['admin']; ?>.
</p>
<p>
Thank you.
</p>
<div class="version">
<?php echo date('Y-m-d H:i:s',$data['time']) .' '. $data['version']; ?>
</div>
</body>
You will have access to following attributes in your $data array
code: the HTTP status code (e.g. 403, 500);
type: the error type (e.g. CHttpException, PHP Error);
message: the error message;
file: the name of the PHP script file where the error occurs;
line: the line number of the code where the error occurs;
trace: the call stack of the error;
source: the context source code where the error occurs.
The alternative technique is how you created an action in SiteController,however to activate this you need to change your main config file and route errors to this action:
return array(
......
'components'=>array(
'errorHandler'=>array(
'errorAction'=>'site/error',
),
),
);
If you wish to only skin your errors then this is not necessary, if you want to do more complex stuff like on error log to a DB, send a email to the admin etc then it is good to have your own action with additional logic.

Yii: Same route but only GET works after confirming there's no controller filter

My urlManager rules: (basically the one comes default)
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',`
My controller:
class SiteController extends Controller {
public function actionSubscribe() {
echo 'gdg';
die();
}
}
My view:
<form method="POST" action="<?php echo $this->createUrl('site/subscribe'); ?>" style="display: inline;">
<input style="margin: 0 18px 0 6px;" type="text" value="e-mail"/>
</form>
When I access it using the url http://localhost/site/subscribe directly it works, but when I type something in the text field and push my enter button to post the form it says The system is unable to find the requested action "error".
I'm very certain that it has something to do with my form. I have so far no problem using active form but for this form I don't have a model and I don't want to use form builder. Any help?
"When I access it using the url http://*/site/subscribe directly it works"
=> You execute subscribe action with GET method.
"but when I type something in the text field and push my enter button to post the form it says The system is unable to find the requested action "error"."
=> You execute subscribe action with POST method.
=> There are some errors and I think Yii try to handle error with your default configure:
return array(
......
'components'=>array(
'errorHandler'=>array(
'errorAction'=>'site/error',
),
),
);
However, Yii can't find error action with your SiteController so it throws The system is unable to find the requested action "error". You can add error action to see information about errors like:
public function actionError()
{
if($error=Yii::app()->errorHandler->error){
$this->render('error', $error);
}
}
More info: The above error variable is an array with the following fields:
code: the HTTP status code (e.g. 403, 500);
type: the error type (e.g. CHttpException, PHP Error);
message: the error message;
file: the name of the PHP script file where the error occurs;
line: the line number of the code where the error occurs;
trace: the call stack of the error;
source: the context source code where the error occurs.

yii CHtml::button and POST request to controller

Is there a way to have CHtml::button send a post request to the controller
<?php echo CHtml::button('Button Text', array('submit' => array('controller/action'))); ?>
I'm looking to replicate the CHtml::linkfunctionality and POST to the controller
<?php echo CHtml::link('Delete',"#", array("submit"=>array('delete', 'id'=>$data->ID), 'confirm' => 'Are you sure?')); ?>
EDIT:
The button is NOT submitting a form
Try this:
echo CHtml::button('Delete',
array(
'submit'=>array('controllername/actionname',array('id'=>$id)),
'confirm' => 'Are you sure?'
// or you can use 'params'=>array('id'=>$id)
)
);
As you'll see button also takes the special htmlOptions attribute clientChange.
Update Clarification of submit, from the doc link ():
submit: string, specifies the URL to submit to. If the current element has a parent form, that form will be submitted, and if 'submit' is non-empty its value will replace the form's URL. If there is no parent form the data listed in 'params' will be submitted instead (via POST method), to the URL in 'submit' or the currently requested URL if 'submit' is empty. Please note that if the 'csrf' setting is true, the CSRF token will be included in the params too.
emphasis mine
As you mentioned that you want to hit the delete action, the default gii generated actionDelete expects the id in the url, hence I passed the id in the url, i.e submit option.

How to control where YII flashes are placed?

With YII Flashes you can do this:
Yii::app()->user->setFlash('success', "Data saved!");
However, when the flash appears on the page, it appears like so:
<div id="yw1">
<div class="alert in alert-block fade alert-info"><a class="close" data-dismiss="alert">×</a>
MESSAGE
</div>
</div>
How do I control WHERE this is placed? I don't see anything in layouts/main.php that controls this, yet they display?
They won't display anywhere unless you are calling them, a good example in the Yii default app is the site/contact view:
<?php if(Yii::app()->user->hasFlash('contact')): ?>
<div class="flash-success">
<?php echo Yii::app()->user->getFlash('contact'); ?>
</div>
<?php else: ?>
...
And the flash is set using the setFlash method
Yii::app()->user->setFlash('contact','Thank you for contacting us. We will respond to you as soon as possible.');
A possibility is that there may be a check in the Controller root class (protected/components/Controller.php), where someone may have written an init() function that checks for them. This would be called on every controller/action call so it may be there.
Another possibility is that whoever created the project edited the flash method in the framework folder (or possibly extended it), you could have a look there, it is in framework/web/auth/CWebUser.php
But as Mik said, try doing a text search in your project for getFlash or even just flash
I would do a textsearch on user->getFlashes() in your views folder. You can output the messages at any place with this
<?php
foreach(Yii::app()->user->getFlashes() as $key => $message) {
echo '<div class="flash-' . $key . '">' . $message . "</div>\n";
}
?>
You, the developer, need to display flash-messages. Yii does not do that for you.
You display them in a view, as shown by Eskimo and Mik, at a location of your own choosing . Yii could never do that, because Yii does not know the layout of your view.

CCaptcha displaying no image yii

I have a user registration form, in which I am trying to display a Captcha image by using Yii widget CCaptcha, however my image link appears broken,
Controller file:
public function actions()
{
return array(
// captcha action renders the CAPTCHA image displayed on the contact page
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xFFFFFF,
),
);
}
Model File:
public function rules()
{
return array( array('verifyCode','captcha','allowEmpty'=>!CCaptcha::checkRequirements(),'on'=>'insert'),
);
}
And view file:
<?php if(CCaptcha::checkRequirements()): ?>
<div class="row">
<?php echo $form->labelEx($model,'verifyCode'); ?>
<div>
<?php $this->widget('CCaptcha'); ?>
<?php echo $form->textField($model,'verifyCode'); ?>
</div>
<div class="hint">Please enter the letters as shown.
<br/>Letters are not case-sensitive.</div>
<?php echo $form->error($model,'verifyCode'); ?>
</div>
<?php endif; ?>
As a answer provided somewhere I also tried giving the access rules in my controller file as
public function accessRules()
{
return array(
array('allow',
'actions' => array('captcha'),
'users' => array('*'),
),
);
}
But nothing seems to be working.
The problem was with the controller file,it should have been,
public function accessRules()
{
return array(
array('allow',
'actions'=>array('create', 'captcha'),
'users'=>array('*'),
),
}
whereas I had mentioned the action for captcha at the end, which I figured out is not allowed in Yii. All the allow actions for * should be together.
Yii captcha will create a png image. A possible explanation for the broken image link would be a missing GD extension or imagick extension, which can be identified by the presence of the following text in your error.log:
call to undefined function imagecreatetruecolor
For details and fix see "call to undefined function imagecreatetruecolor" error in PHP & pChart