Form Validation error on Yii Framework? - php

I'm new on Yii, I have Try Crud and succes. now try to create validation but Still error.
here my script
Model:Buku.php
public function rules()
{
return array(
array('judul, penulis'),
array('judul', 'length','max'=>50),
array('penulis', 'length', 'max'=>50),
array('judul,penulis', 'on'=>'search'),
);
}
Controller: BukuController.php
public function actionCreate()
{
$model = new Buku;
if(isset($_POST['Buku']))
{
$model->judul =$_POST['Buku']['judul'];
$model->penulis =$_POST['Buku']['penulis'];
$model->save();
/*if($model->save())
{
Yii::app()->user->setFlash('Succes', "Data berhasil Disimpan");
$this->redirect(array('index'));
}*///end of
}//end if isset
$this->render('create',array('model'=>$model));
}//end of class
View: create.php
<div class="form">
<h2>Add Data</h2>
<?php echo CHtml::beginForm(array('buku/create'));?>
<?php
echo CHtml::errorSummary($model);
?>
<div class="row">
<?php echo CHtml::activeLabel($model,'judul');?>
<?php echo CHtml::activeTextField($model,'judul','');?>
<?php echo CHtml::errorSummary($model,'judul');?>
</div>
<div class="row">
<?php echo CHtml::activeLabel($model,'penulis');?>
<?php echo CHtml::activeTextField($model,'penulis','');?>
<?php echo CHtml::errorSummary($model,'penulis');?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Submit');?>
<?php echo CHtml::endForm();?>
</div>
</div>
the Error MEssage is
Buku has an invalid validation rule. The rule must specify attributes to be validated and the validator name
Anyone can Help This?
Im very appreciated Your answer.
Thanks

Pleas edit the first line, probably you wanted there 'required'
array('judul, penulis','required'),
And this is not needed:
$model->judul =$_POST['Buku']['judul'];
$model->penulis =$_POST['Buku']['penulis'];
instead you can use the mass-assignment: http://www.yiiframework.com/wiki/161/understanding-safe-validation-rules/
$model->attributes=$_POST['Buku'];

In Your Model class method rules first rule is invalid:
array('judul, penulis') -> no validation rule specified.
Try at least:
array('judul, penulis', 'required')
List of all Validation rules in Yii:
http://www.yiiframework.com/wiki/56/

How validation works
Parameters of a validator
Choice of validators
Scenarios
Validation rules reference
boolean : CBooleanValidator
captcha : CCaptchaValidator
compare : CCompareValidator
date : CDateValidator
default : CDefaultValueValidator
email : CEmailValidator
exist : CExistValidator
file : CFileValidator
filter : CFilterValidator
in : CRangeValidator
length : CStringValidator
numerical : CNumberValidator
match : CRegularExpressionValidator
required : CRequiredValidator
safe : CSafeValidator
type : CTypeValidator
unique : CUniqueValidator
unsafe : CUnsafeValidator
url : CUrlValidator
Selected readings
Built in validators in Yii....

Related

Codeigniter form validation return always false

In my codeigniter controller function call $this->form_validation->run(), that return always false, and my validation_errors() not showing error, probably because not receive datas in post method...
my controller
class Reminder extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('reminder_model');
$this->load->helper('form');
$this->load->library('form_validation');
$this->load->helper('url');
$this->load->library('email');
$this->load->library('session');
if(!$this->session->auth_ok) {
redirect('auth/login');
}
}
public function index(){
$data['title'] = 'Reminder';
$data['section'] = 'reminder';
$data['reminders'] = $this->reminder_model->getReminders();
$data['operatori'] = $this->reminder_model->getOperators();
$this->form_validation->set_rules('selectUser','selectUser', '');
if($this->form_validation->run() === FALSE) {
$this->load->view('common/header2', $data);
$this->load->view('reminder/index', $data);
$this->load->view('common/footerReminder');
echo validation_errors();
}else{
echo "<pre>";
print_r($this->input->post());
die();
}
}
my view
<?php echo form_open('reminder/index'); ?>
<div class="form-group">
<label for="selectUser" style=" width: 30%">Utente: </label>
<select class="form-control" name="selectUser" id="selectUser" style="width: 30%">
<?php foreach($operatori as $operatore): ?>
<option value="<?php echo $operatore['ID']?>" <?php echo $r = ($operatore['ID']==$this->session->auth_user['ID']) ? 'selected' : '' ?>><?php echo $operatore['nome']." ".$operatore['cognome'] ?></option>
<?php endforeach; ?>
</select>
</div>
<button type="submit" class="btn btn-primary"><i class="fas fa-search"></i> View</button>
<?php echo form_close(); ?>
In order to get the entire $_POST array using CodeIgniters built-in methods, you have to set the first parameter as NULL and the second parameter as TRUE
Like this:
$this->input->post(NULL, TRUE);
Also, you have not set any rules for validation..
In CodeIgniter, you set rules in the third parameter of the set_rules method within the form_validation object.
Like this:
$this->form_validation->set_rules($FIELD_NAME, $FIELD_NAME(for error messages), $RULES);
You would substitute the first $FIELD_NAME with the value of the name attribute on the HTML element you are looking to validate.
You would substitute the second $FIELD_NAME with the name you would like to use for the field when displaying an error message to the user.
You would substitute $RULES with the validation rules such as: 'required|min_length[#]|max_length[#]'
Hope this helps!
If you are not setting rules (which makes it rather pointless to use $this->form_validation->set_rules()) the form validation will fail as it's missing a required parameter.
If you don't need to validate a field, don't set a rule.
Try updating your set_rules instruction to $this->form_validation->set_rules('selectUser','selectUser', 'required'); to see if it behaves correctly. You can verify by filling something in the form (validation will pass) or leaving the field blank (validation will fail)
Just remember, if you won't set at least one validation rule for a field, don't instantiate the set_rules method for that field

yii validate an input array of phone numbers

I'm working on a multiple contact form in Yii 1.1.16. Where the user can add multiple phone numbers.
Problem is, how would i validate this using Yii's rules()?
<div class="form-group">
<?php
echo $form->labelEx($model,'contacts', array('class'=>'col-md-3 control-label'));
?>
<div class="col-md-9">
<div class="multiple-contact multiple-form-group input-group padding-bottom-10px" data-max="5">
<div class="input-group-btn input-group-select">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="concept">Phone</span> <i class="fa fa-caret-down"></i>
</button>
<ul class="dropdown-menu" role="menu">
<li>Phone</li>
<li>Fax</li>
<li>Mobile</li>
</ul>
<?php echo $form->textField($model,'contacts',array('type'=>'text', 'class'=>'input-group-select-val', 'name'=>'contacts[type][]','value'=>'phone')); ?>
</div>
<?php echo $form->textField($model,'contacts',array('size'=>60,'maxlength'=>255, 'name'=>'contacts[value][]','class'=>'form-control')); ?>
<?php echo $form->error($model,'contacts'); ?>
<span class="input-group-btn">
<button type="button" class="btn btn-success btn-add"><i class="fa fa-plus"></i></button>
</span>
</div>
</div>
</div>
i tried using this, but doesn't work
public function rules()
{
return array(
array('contacts[value][]', 'required'),
array('contacts[value][]', 'integerOnly'=>true),
array('contacts[value][]','type','type'=>'array','allowEmpty'=>false)
);
}
Here is a sample Fiddle on how the jQuery side works. I want it to be able to validate with 'enableAjaxValidation'=>true,. Also, when more fields are added, it duplicates the id of the input. and no ajax post is done onblur/onfocus
Use custom validation.
Declare a custom validator in your rules, and define the validation you require in the validator method.
public function rules()
{
return array(
array('contacts', validateContacts),
);
}
public function validateContacts($attribute,$params)
{
if (length($this->contacts) == 0) {
$this->addError($attribute, 'You must add at least one contact!');
}
foreach($this->contacts as $contact) {
// ...
}
}
In your controller, assign the contacts array to the Model field and call the model's validation method. If there are any errors it will display through the line
<?php echo $form->error($model,'contacts'); ?>
in the view.
The controller contains the code to invoke the validation.
$contactModel = new Contact;
// assign the array of contacts to the model
$contactModel->contacts = $POST['myForm]['contacts']
$contactsModel->validate();
$this->render('myform', contactModel);
If you want the validation to happen through Ajax, you need to specify so when creating your form:
$form=$this->beginWidget('CActiveForm', array(
'id'=>'top-websites-cr-form',
'enableAjaxValidation'=>true,
'clientOptions' => array(
'validateOnSubmit'=>true,
'validateOnChange'=>true),
));
In this case your controller can check for ajax forms.
if(isset($_POST['ajax']) && $_POST['ajax']==='branch-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
references:
http://www.yiiframework.com/wiki/168/create-your-own-validation-rule/
You should make it a separate model with it's own validation.
Then in your controller you have to validate the main models and the related models separately.
Here is a good guide for such a setup:
http://www.yiiframework.com/wiki/384/creating-and-updating-model-and-its-related-models-in-one-form-inc-image/
To my opinion for best validation regarding phonenumbers you should use libphonenumber php library and there is an extension for it regarding yii framework here http://www.yiiframework.com/extension/libphonenumber/
basic usage:
Yii::setPathOfAlias('libphonenumber',Yii::getPathOfAlias('application.vendors.libphonenumber'));
$phonenumber=new libphonenumber\LibPhone($your_phone_number);
$phonenumber->validate();
for more details regarding usage and capabilities of libphonenumber php library you can find here:
https://github.com/davideme/libphonenumber-for-PHP
Let us consider you have a model called ContactNo and it looks like
class ContactNo extends CFormModel
{
public $contact;
public function rules()
{
return array(
// your rules
array('contact', 'required'),
array('contact','length','min'=>2)
);
}
/**
* Declares attribute labels.
*/
public function attributeLabels()
{
return array(
'contact'=>'Contact No',
);
}
}
The controller as SiteController and the action Name as actionIndex
Then your controller should look something like this
public function actionIndex()
{
// set how many contact fields you want here
$contactCount = 3;
$models = array();
if(isset($_POST['ContactNo']))
{
$successModels = 0;
foreach($_POST['ContactNo'] as $key=>$value)
{
$model = new ContactNo;
$model->attributes = $value;
if($model->validate()) // this validates your model
$successModels++; // it tells how many contact No.s have been validated
$models[$key]=$model;
}
// if all the contact nos are validated, then perform your task here
if($successModels === $contactCount)
{
// save your models
echo 'models saved';
Yii::app()->end();
}
}
else
{
for($index = 0;$index < $contactCount; $index++)
$models[] = new ContactNo;
}
$params = array();
$params['contactCount']=$contactCount;
$params['models']= $models;
$this->render('index',$params);
}
Now lets Go to view. Obviously the view is index.php and it will be something like
// Include all the initial part required for activeforms
<?php echo $form->errorSummary($models); ?>
<?php foreach ($models as $index=>$model): ?>
<div class="row">
<?php echo $form->labelEx($model,"[{$index}]contact"); ?>
<?php echo $form->textField($model,"[{$index}]contact",array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,"[{$index}]contact"); ?>
</div>
<?php endforeach; ?>
// Include the submit button
Hope this helps you or might give you an idea atleast to achieve your goal.

Comapring rule between two variables in rules not working in Yii

I am doing a function to change the users password. Inside of the Users model I have create three variable like the following.
public $oldPassword;
public $newPassword;
public $repatePassword;
Now I need to compare newPassword and repare password together and i added the followinf rule inside of the model.
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('username, password', 'required'),
array('username', 'length', 'max'=>20),
array('password', 'length', 'max'=>255),
array('oldPassword', 'findPassword', 'on' => 'changePwd'),
//array('repatePassword','compare','compareAttribute'=>'newPassword', 'on'=>'changePwd'),
// The following rule is used by search().
// #todo Please remove those attributes that should not be searched.
array('id, username, password', 'safe', 'on'=>'search'),
);
}
I have the following form.
<div class="row">
<?php echo $form->labelEx($model,'Old Password'); ?>
<?php echo $form->passwordField($model,'oldPassword',array('size'=>20,'maxlength'=>20)); ?>
<?php echo $form->error($model,'oldPassword'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'New Password'); ?>
<?php echo $form->passwordField($model,'newPassword',array('maxlength'=>255)); ?>
<?php echo $form->error($model,'newPassword'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'Repate Password'); ?>
<?php echo $form->passwordField($model,'repatePassword',array('maxlength'=>255)); ?>
<?php echo $form->error($model,'repatePassword'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Update'); ?>
</div>
Now when I exactly put the exc same values in both of the fields it still gives me that the values are not the same. Why is this?
Add the following rule to your rules() method.
array('oldPassword,newPassword,repatePassword','required','on'=>'changePwd')
Without a rule for an attribute, that attribute will NOT be massively assigned to the model and so will not be available for any validation.
Alternately, you can change required to be safe if you just want to allow assignment, and not make the attributes actually required, although in this case required makes sense to me.
Based on your rules, the reason it says they do not match is because newPassword is not being assigned, and so is an empty string being compared to your intended password.

How to save input in yii to database

I have this code Im trying to save the content and the title from a form I made..It has an id that autoincrement the id number adds in the database but the title and the content isn't/cant be save in the database. Can you please check my code if I've done something wrong? or what I'm lacking at.
Here is my model ContentForm.php
<?php
class ContentForm extends CActiveRecord{
public $content;
public $title;
public function tableName(){
return 'tbl_content';
}
public function attributeLabels()
{
return array(
'contentid' => 'contentid',
'content' => 'content',
'title' => 'title',
// 'email' => 'Email',
// 'usrtype' => 'Usrtype',
);
}
Here is my view content.php
<div>
<p>User: <a href="viewuserpost">
<?php
echo Yii::app()->session['nameuser'];
?>
</a>
</p>
</div>
<h1>Content</h1>
<?php
$form=$this->beginWidget('CActiveForm', array(
'id'=>'contact-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
));
?>
Title:
<div class="row">
<?php
echo $form->textfield($model,'title');
?>
</div>
</br>
Body:
<div class="row">
<?php
echo $form->textArea($model,'content',array('rows'=>16,'cols'=>110));
?>
</div>
<div class="row buttons">
<?php
echo CHtml::submitButton($model->isNewRecord? 'Create':'Save');
?>
</div>
<?php $this->endWidget(); ?>
and here is my content action in my sitecontroller.php
public function actionContent(){
$model=new ContentForm;
if(isset($_POST['ContentForm'])) {
$model->attributes=$_POST['ContentForm'];
if($model->save())
$this->redirect(array('content','contentid'=>$model->contentid));
$this->redirect(array('content','title'=>$model->title));
$this->redirect(array('content','content'=>$model->content));
}
$this->render('content',array('model'=>$model));
}
Please help.
Remove
public $content;
public $title;
from your class.
Yii uses PHP magic methods. And when you add attributes to your class, PHP doesn't call them but references to your explicitly written attributes.
Moreover, you should add some validation, if you use $model->attributes=$_POST['ContentForm'];. Another variant is to use unsecure $model->setAttributes($_POST[ContentForm], false) where false tells Yii to set all attributes, not only that are considered safe.
Note, that attributes is not real Model attribute, this is virtual attribute accessed through magic methods.
Also, you don't need three redirects. This is HTTP redirect to other page. This time, you just should just specify route to model view action and its parameter that is id, for example. Like this $this->redirect(array('content/view','id'=>$model->contentid));.
Of course, simplest way for you is to create new model and controller with actions using Gii.
you may missed rules , add this in your model ContentForm.php
public function rules()
{
return array(
array('content,title', 'safe'),
);
}
For more about model validation
http://www.yiiframework.com/wiki/56/reference-model-rules-validation/

Yii: Submit a value to different model

Here's a newbie question related to my latest exercise with Yii Framework.
I have a following structure in the database:
CREATE TABLE location(
id INTEGER PRIMARY KEY NOT NULL,
location TEXT);
CREATE TABLE parameter(
id INTEGER PRIMARY KEY NOT NULL,
name TEXT,
value TEXT);
CREATE TABLE temperature(
id INTEGER PRIMARY KEY NOT NULL,
locationId INTEGER,
value REAL NOT NULL,
createDate DATETIME NOT NULL,
FOREIGN KEY(locationId) REFERENCES location(id));
CREATE INDEX idx1_temperature ON temperature (createDate);
I'm trying to create a view containing both location data in a grid, but also a functionality to change a certain value in parameter-table. In practice I would have a list of all possible locations in a grid, in addition to a possibility to change the parameter.value where parameter.name="CURRENT_LOCATION".
What I've gotten so far is:
location/admin.php generating a view:
...
<h2>Change current location</h2>
<?php echo $this->renderPartial('_para', array('model'=>Parameter::model()->find('name="current_location"'))); ?>
<h2>Modify locations</h2>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'location-grid',
'dataProvider'=>$model->search(),
'columns'=>array(
'location',
array(
'class'=>'CButtonColumn',
),
),
));
...
location/_para.php for embedding a form:
<?php
/* #var $this ParameterController */
/* #var $model Parameter */
/* #var $form CActiveForm */
?>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'parameter-form',
'enableAjaxValidation'=>false,
)); ?>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'value'); ?>
<?php //echo $form->textField($model,'value'); ?>
<?php echo $form->dropDownList($model,'value',CHtml::listData(Location::model()->findAll(), 'id', 'location')); ?>
<?php echo $form->error($model,'value'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
So, what would need is to Save(=update) a given parameter-row, but I just seem not to get it right. I have debugged so far that it seems like the Submit Button causes the Location-controller's actionAdmin-function to be executed. That would be fine by me, if I just could instruct there to save the Parameter-record instead of the Location.
Here's the actionAdmin-function from LocationController.php:
public function actionAdmin()
{
$model=new Location('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['Location']))
{
$model->attributes=$_GET['Location'];
}
if(isset($_POST['Parameter']))
{
$model->attributes=$_POST['Parameter'];
if($model->save())
{
$this->redirect(array('view','id'=>$model->id));
}
}
$this->render('admin',array(
'model'=>$model,
));
}
I see a lot to posts covering multi model forms and such, but I just cannot get a grip on this. It may very well be that I'm trying to accomplish this in a totally wrong way.
So, punch me to right direction, please.
Okay so, I think the best thing is to put the method for updating the Parameter in the ParameterController. That makes it easier to implement and is a bit cleaner.
So to do that, change the form code to this:
You might need to adjust the action in the form for it to work, e.g. /admin/parameter/update
<?php
/* #var $this ParameterController */
/* #var $model Parameter */
/* #var $form CActiveForm */
?>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'parameter-form',
'enableAjaxValidation'=>false,
// Check that the action method below is correct
'action' => array('/parameter/update', 'id' => $model->id),
)); ?>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'value'); ?>
<?php //echo $form->textField($model,'value'); ?>
<?php echo $form->dropDownList($model,'value',CHtml::listData(Location::model()->findAll(), 'id', 'location')); ?>
<?php echo $form->error($model,'value'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
If you have an existing update method in your ParameterController, see if it works as is. If it doesn't or you don't have the update method, try something like this:
public function actionUpdate($id)
{
$model = Parameter::model()->findByPk($id);
if(isset($_POST['Parameter']))
{
$model->attributes=$_POST['Parameter'];
if($model->update())
{
// Below redirects to the previous URL
$this->redirect(Yii::app()->request->urlReferrer);
}
}
}
I changed $model->save() to $model->update() because that won't call the validation rules and make it return false. If you want to validate for some reason, you will need to change the rule so that name and value are only required when creating a new parameter, like this:
array('name, value', 'required', 'on' => 'create'),
And then when you create your new Parameter, you would need to do $model = new Parameter('create');

Categories