codeigniter form validation always returns false even when rules met - forms

Problem: even if my form fields meet the rules the codeigniter form validation still returns false (error).
example:
public function edit(){
$this->load->library('form_validation');
$this->form_validation->set_rules('title', 'title', 'required|xss_clean|trim|is_unique[news.Title]');
$this->form_validation->set_rules('description', 'description', 'required|xss_clean|trim');
$this->form_validation->set_rules('notes', 'notes', 'required|xss_clean|trim');
if ($this->form_validation->run() == FALSE)
{
$data['error'] = '';
$data['page_title']="Edit News";
echo "error";
}
else {
..........
if i leave the fields empty it will tell me to enter something because they cant be left empty. if i type something then it returns error once i submit the form.

you have to use the callback validation function
you have to pass id also
$this->form_validation->set_rules('title', 'Title', 'required|xss_clean|trim|callback_check_title');
function check_title($title) {
if($this->input->post('id'))
$id = $this->input->post('id');
else
$id = '';
$result = $this->news_model->check_unique_title($id, $title);
if($result == 0)
$response = true;
else {
$this->form_validation->set_message('check_title', 'Title must be unique');
$response = false;
}
return $response;
}
in model
function check_unique_title($id, $title) {
$this->db->where('title', $title);
if($id) {
$this->db->where_not_in('id', $id);
}
return $this->db->get('news')->num_rows();
}
it will work for both insert and update

no need for callback function
The problem is : codeigniter database class is not loaded;
You should load database : $this->load->database(); before running
if ($this->form_validation->run() == FALSE)
{
$data['error'] = '';
$data['page_title']="Edit News";
echo "error";
}

Related

Codeigniter Call to a member function where() on bool

I tried to set seen to any contact data in database, but when i try that:
public function showMessage($id){
$this->load->model('Message_Model');
$messageData = $this->Message_Model->selectMessage($id);
if($messageData[0]->messageIsSeen == 0){
$this->Message_Model->setSeenToMessage($id);
}
$data = array('messageData' => $messageData[0]);
$this->load->view('Back/MessageDetail', $data);
}
Model:
function setSeenToMessage($id){
$this->db->update('messages', array('messageIsSeen' => 1))->where('messageId', $id);
return 1;
}
It throws that error
i solved it like this change
function setSeenToMessage($id){
$this->db
->where('messageId', $id);
->update('messages', array('messageIsSeen' => 1))
return 1;
}
nevertheless, still i don't know how did it works

Login Page Hash issue UPDATE

I am having a issue with my login page reading a function to login
on my register page which I'm proud to say works perfect
this is my password hash code
$password = password_hash($password, PASSWORD_BCRYPT);
my login page has 2 fields
email &
password
I have re cleaned my code and solved the issue some what
functions are working
when I enter email and password it triggers
Warning! Email or Password Incorrect
plus an error at the top
Notice: Undefined index: password in C:\Program Files (x86)\Zend\Apache2\htdocs\CMS\functions\functions.php on line 249
this is line 249
$db_password = $row['password'];
/* Validate Login */
function validate_login()
{
$errors = [];
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$email = clean($_POST['email']);
$password = clean($_POST['password']);
if (empty($email)) {
$errors[] = "Email Required";
}
if (empty($password)) {
$errors[] = "Password Required";
}
if (! empty($errors)) {
foreach ($errors as $error) {
echo validation_errors($error);
}
} else {
if (login_user($email, $password)) {
redirect("../account/profile.php");
} else {
echo validation_errors("Email or Password Incorrect");
}
}
}
} // End Function
/* User Login */
function login_user($email, $password)
{
$sql = "SELECT user_pwd, uid FROM userss WHERE user_email = '" . escape($email) . "'";
$result = query($sql);
if (row_count($result) == 1) {
$row = fetch_array($result);
$db_password = $row['password'];
if (hash_algos($password) == $db_password) {
return true;
} else {
return false;
}
}
}// End Function
It looks like you are missing a closing bracket for your validate_login() function so it is defining the login_user() function only after the first function is called. Therefore as you progress through your validate_login() function you call the login_user() function before it is created since it is created after the if statement completes.
OK I just figured out the issue
if (hash_algos($password) == $db_password) {
return true;
} else {
return false;
}
changed it to this
if(password_verify($password, $db_password)){
return true;
} else {
return false;
}

Zend form validation multiple custom validation message for same field at the same time

I have a Zend form password custom validation.
I have set the addValidator functions IInd argument to false since I need to get all errors at once. Both of my validation classes have set the self::INVLID to corresponding error messages.
But when I look in the Zend controller even though both validations fail I'm getting only one (the last) error message.
I need all the error messages at once.
/* Form validation*/
$passwordSpecialValidator = new Passwordspecialvalidationvalidator();
$passwordHistoryValidator = new Passwordhistorylvalidationvalidator(new model(), $username, $newpass);
$this->newpass->addValidator($passwordSpecialValidator, false)
->addValidator($passwordHistoryValidator, false);
/* One validation class */
class Passwordhistorylvalidationvalidator extends Zend_Validate_Abstract {
const INVLID = '';
protected $_messageTemplates = array(
self::INVLID => 'Your password doesnt meet the history requirements'
);
public function __construct($model, $username, $password) {
$this->_model = $model;
$this->_username = $username;
$this->_password = $password;
}
public function isValid($value, $context = null) {
if ($this->_username == "") {
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$arrayResult = $auth->getIdentity();
if (isset($arrayResult->username)) {
$this->_username = $arrayResult->username;
}
}
}
$passwordExists = false;
$oldPasswords = $this->_model->getHistoryPasswords($this->_username, $this->_password);
if (count($oldPasswords) > 0) {
$passwordExists = true;
}
if ($passwordExists == false) {
return true;
} else {
$this->_setValue($value);
$this->_error(self::INVLID);
return false;
}
}
}
/* Getting error messages */
foreach ($objForm->getMessages() as $messages) {
foreach ($messages as $message) {
$errMessages[] = $message;
}
}
But the array $errMessages has only the last validation message (without index) even though both special validation and history validation fails. How would I get both error messages in an array if both validations fail?

concatenate fields with zend_form

I'm using the zend framework with centurion and I'm having a problem with my form. I have fields num_ordre and code, both of which are primary keys and I have columns in my table named conca, it's the concatenation of two fields, num_ordre and code.
My question is, in my method post, I want to test if the concatanation of num_ordre and code already exists in my database; but the problem is how to take a value of to fields before posting it.
This is my code
public function postAction(){
$this->_helper->viewRenderer->setNoRender(TRUE);
$user = new Param_Model_DbTable_Verification();
$form= $this->_getForm();
$form->getElement('Num_ordre')->addValidator(new Zend_Validate_Db_NoRecordExists('verifications','Num_ordre'));
$form->getElement('Num_ordre')->setRequired(true);
$posts = $this->_request->getPost();
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$row=$user->createRow();
$row->code=$this->_getParam('code');
$row->Num_ordre=$this->_getParam('Num_ordre');
$row->Libelle_champ=$this->_getParam('Libelle_champ');
$row->comparaison=$this->_getParam('comparaison');
$row->formule=$this->_getParam('formule');
$row->obligatoire=$this->_getParam('obligatoire');
$row->Req_traduction=$this->_getParam('Req_traduction');
$row->tolerance_erreur=$this->_getParam('tolerance_erreur');
$row->Mess_erreur=$this->_getParam('Mess_erreur');
$row->conca=$this->_getParam('Num_ordre').$this->_getParam('code');
$row->save();
if( isset ($posts['_addanother'])){
$_form = $this->_getForm();
$_form->removeElement('id');
$this->_helper->redirector('new','admin-verification');
}
else
$this->_helper->redirector(array('controller'=>'Admin-verification'));
}else{
parent::postAction();
}
}}
How about you just check it like this ?
public function postAction(){
$this->_helper->viewRenderer->setNoRender(TRUE);
$user = new Param_Model_DbTable_Verification();
$form= $this->_getForm();
$form->getElement('Num_ordre')->addValidator(new Zend_Validate_Db_NoRecordExists('verifications','Num_ordre'));
$form->getElement('Num_ordre')->setRequired(true);
$posts = $this->_request->getPost();
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
$mdl = new Model_Something(); //Call your model so you can test it
//Add a condition here
if ($form->isValid($formData) && $mdl->uniqueConcatenated($this->_getParam('num_ordre'), $this->_getParam('code')) {
$row=$user->createRow();
/**truncated, keep your existing code here**/
}
}
}
Then in your model Model_Something
public function uniqueConcatenated($numOrder, $code) {
$concatenated = $numOrder.$code;
//Check for the existence of a row with the concatenated field values
$select = $this->select();
$select->where('concatenatedField = '.$concatenated);
$row = $this->fetchRow($select);
return $row;
}
Hope this helps
You could manually call isValid on the validator:
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$formValues = $form->getValues();
$uniqueValidator = new Zend_Validate_Db_NoRecordExists('verifications','conca');
if ($uniqueValidator->isValid($formValues['Num_ordre'] . $formValues['Num_ordre'])) {
// valid
} else {
// not unique
}
}
untested code

Yii form model validation- either one is required

I have two fields on the form ( forgotpassword form ) username and email Id . User should enter one of them . I mean to retrieve the password user can enter user name or the email id . Could some one point me the validation rule for this ?
Is there any inbuilt rule I can use ?
( Sorry if it is already discussed or if I missed)
Thanks for your help
Regards
Kiran
I was trying to solve same problem today. What I've got is the code below.
public function rules()
{
return array(
// array('username, email', 'required'), // Remove these fields from required!!
array('email', 'email'),
array('username, email', 'my_equired'), // do it below any validation of username and email field
);
}
public function my_required($attribute_name, $params)
{
if (empty($this->username)
&& empty($this->email)
) {
$this->addError($attribute_name, Yii::t('user', 'At least 1 of the field must be filled up properly'));
return false;
}
return true;
}
General idea is to move 'required' validation to custom my_required() method which can check if any of field is filled up.
I see this post is from 2011 however I couldn't find any other solution for it. I Hope it will work for you or other in the future.
Enjoy.
Something like this is a bit more generic and can be reused.
public function rules() {
return array(
array('username','either','other'=>'email'),
);
}
public function either($attribute_name, $params)
{
$field1 = $this->getAttributeLabel($attribute_name);
$field2 = $this->getAttributeLabel($params['other']);
if (empty($this->$attribute_name) && empty($this->$params['other'])) {
$this->addError($attribute_name, Yii::t('user', "either {$field1} or {$field2} is required."));
return false;
}
return true;
}
Yii2
namespace common\components;
use yii\validators\Validator;
class EitherValidator extends Validator
{
/**
* #inheritdoc
*/
public function validateAttributes($model, $attributes = null)
{
$labels = [];
$values = [];
$attributes = $this->attributes;
foreach($attributes as $attribute) {
$labels[] = $model->getAttributeLabel($attribute);
if(!empty($model->$attribute)) {
$values[] = $model->$attribute;
}
}
if (empty($values)) {
$labels = '«' . implode('» or «', $labels) . '»';
foreach($attributes as $attribute) {
$this->addError($model, $attribute, "Fill {$labels}.");
}
return false;
}
return true;
}
}
in model:
public function rules()
{
return [
[['attribute1', 'attribute2', 'attribute3', ...], EitherValidator::className()],
];
}
I don't think there is a predefined rule that would work in that case, but it would be easy enough to define your own where for username and password fields the rule was "if empty($username . $password) { return error }" - you might want to check for a min length or other field-level requirements as well.
This works for me:
['clientGroupId', 'required', 'when' => function($model) {
return empty($model->clientId);
}, 'message' => 'Client group or client selection is required'],
You can use private property inside model class for preventing displays errors two times (do not assign error to model's attribute, but only add to model without specifying it):
class CustomModel extends CFormModel
{
public $username;
public $email;
private $_addOtherOneOfTwoValidationError = true;
public function rules()
{
return array(
array('username, email', 'requiredOneOfTwo'),
);
}
public function requiredOneOfTwo($attribute, $params)
{
if(empty($this->username) && empty($this->email))
{
// if error is not already added to model, add it!
if($this->_addOtherOneOfTwoValidationError)
{
$this->addErrors(array('Please enter your username or emailId.'));
// after first error adding, make error addition impossible
$this->_addOtherOneOfTwoValidationError = false;
}
return false;
}
return true;
}
}
don't forget "skipOnEmpty" attr. It cost me some hours.
protected function customRules()
{
return [
[['name', 'surname', 'phone'], 'compositeRequired', 'skipOnEmpty' => false,],
];
}
public function compositeRequired($attribute_name, $params)
{
if (empty($this->name)
&& empty($this->surname)
&& empty($this->phone)
) {
$this->addError($attribute_name, Yii::t('error', 'At least 1 of the field must be filled up properly'));
return false;
}
return true;
}
Yii 1
It can be optimized of course but may help someone
class OneOfThemRequiredValidator extends \CValidator
{
public function validateAttribute($object, $attribute)
{
$all_empty = true;
foreach($this->attributes as $_attribute) {
if (!$this->isEmpty($object->{$_attribute})) {
$all_empty = false;
break;
}
}
if ($all_empty) {
$message = "Either of the following attributes are required: ";
$attributes_labels = array_map(function($a) use ($object) {
return $object->getAttributeLabel($a);
}, $this->attributes);
$this->addError($object, $_attribute, $message . implode(',',
$attributes_labels));
}
}
}
yii1
public function rules(): array
{
return [
[
'id', // attribute for error
'requiredOneOf', // validator func
'id', // to params array
'name', // to params array
],
];
}
public function requiredOneOf($attribute, $params): void
{
$arr = array_filter($params, function ($key) {
return isset($this->$key);
});
if (empty($arr)) {
$this->addError(
$attribute,
Yii::t('yii', 'Required one of: [{attributes}]', [
'{attributes}' => implode(', ', $params),
])
);
}
}