I already try to googling but not solve, my code below is to check duplicate before insert, when "tagnumber" field already exists will go to specific page and not inserted to table, it works but the problem is although not insert to the table but it wont go to specific page I want.
below is my problem on conditional statements:
if data exists on form validation will execute not insert the data.
if data not exists form validation will execute insert data but go to wrong page (same page with exists data page).
my controoler :
function tambahSubmit()
{
$tagnumber = $this->input->post("tagnumber");
$this->myigniter_model->addData($tagnumber);
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
// field name, error message, validation rules
$this->form_validation->set_rules('tagnumber', 'tagnumber', 'trim|required|is_unique[inventorytag.tagnumber]');
$this->form_validation->set_rules('date', 'date', 'trim|required');
$this->form_validation->set_rules('employee', 'employee', 'trim|required');
$this->form_validation->set_rules('semnumber', 'semnumber', 'trim|required');
$this->form_validation->set_rules('quantity', 'quantity', 'required');
$this->form_validation->set_rules('area', 'area', 'trim|required');
if($this->form_validation->run() == false)
{
$this->load->view('YearEndStock/tampilan_input_gagal');
}
else
{
$this->myigniter_model->addData($tagnumber);
$this->load->view('YearEndStock/tampilan_input_sukses');
}
}
my model :
function addData($tagnumber)
{
// Added $this->db->escape() and limit 1 for Performance
$query = $this->db->query("SELECT tagnumber FROM inventorytag WHERE tagnumber = ".$this->db->escape($tagnumber)." limit 1");
$data = array(
'tagnumber' => $this->input->post('tagnumber'),
'date'=> date('Y-m-d H:i:s'),
'employee' => $this->input->post('employee'),
'semnumber' => $this->input->post('semnumber'),
'quantity' => $this->input->post('quantity'),
'area' => $this->input->post('area')
);
return $query->num_rows() == 0 ? $this->db->insert('inventorytag', $data) : false;
}
Then you just need to separate your true statement. Remove your is_unique validation.
if($this->form_validation->run() == false)
{
SHOW ERRORS
$this->load->view('YearEndStock/tampilan_input_gagal');
}
else
{
$row = $this->db->get_where('inventorytag', array('tagnumber' => $tagnumber))->row();
if (empty($row)) {
//insert
$this->myigniter_model->addData($tagnumber);
} else {
//row exists
}
$this->load->view('YearEndStock/tampilan_input_sukses');
}
Related
After submitting the view page, if the form fields don't contain values then error messages should appear, but in my case, null values are inserted in the database. So please help me where I am going wrong.
If form fields are empty then, if condition should be executed and then view page should be shown with error messages, instead of executing if condition its executing other code and inserting null values in data base.
Controller
public function test_submit()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('test_name', 'Test Name', 'trim|required|is_unique[add_test.TestName]');
$this->form_validation->set_rules('description', 'Description', 'trim|required');
$this->form_validation->set_rules('test_price', 'Test Price', 'trim|required');
$this->form_validation->set_rules('correct_answer', 'Corrent Answer', 'trim|required');
$this->form_validation->set_rules('wrong_answer', 'Wrong Answer', 'trim|required');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('add_test_view');
}
$test_name=$this->input->post('test_name');
$description=$this->input->post('description');
$test_price=$this->input->post('test_price');
$correct_answer=$this->input->post('correct_answer');
$wrong_answer=$this->input->post('wrong_answer');
$insert_data = array(
'TestName' =>$test_name,
'Description' => $description,
'Price' => $test_price,
'CorrectAnswerMarks' => $correct_answer,
'WrongAnswerDeduction' => $wrong_answer
);
$result=$this->test_model->add_test($insert_data);
$this->session->set_tempdata('success', "Test with name ".$test_name." Is Added Successfully.","20");
redirect('testmodule/addtest', 'refresh');
}
You should insert the data in else part of the validation like below:
if ($this->form_validation->run() == FALSE)
{
$this->load->view('add_test_view');
} else {
// Insert code should go here
}
This will ensure data insertion only when validation is succefull.
You should make use of the validation_error() function to display the error message like below:
if ($this->form_validation->run() == FALSE){
$this->session->set_flashdata("error", validation_errors());
redirect('your_controller/your_function');
}
In the above all the errors due to which validtion failed will be displayed on the view. Using redirect also ensures the execution of that function stops there . You have to use below in you view:
<div class="text-danger text-center text-bold"><b><?=$this->session->flashdata('error');?></b></div>
I have implemented a web service for update profile image using Codeigniter framework. But I have an issue while uploading png image. It always gives an error saying -
The filetype you are attempting to upload is not allowed.
Following is my config array:
$config = array(
'upload_path' => BASEPATH .'../assets/uploads/profile_images',
'allowed_types' => 'jpg|png|jpeg',
'overwrite' => TRUE,
'max_size' => "2048000",
);
I have added "png" in allowed types, still it is showing error.
Please guide.
Instead of using
config['allowed_types'] = 'jpg|png|jpeg'
I changed my config array to
$config = array(
'upload_path' => BASEPATH .'../assets/uploads/profile_images',
'allowed_types' => '*',
'overwrite' => TRUE,
'max_size' => "2048000",
);
And added custom form validation rule
$this->form_validation->set_rules('profile_image', '', 'callback_file_check');
and its corresponding function named file_check(). Here I will be checking file type and will return an error if it is not an image.
/**
Function: file_check
Description: file value and type check during validation
Date: 6th July 2018
**/
public function file_check($str)
{
$allowed_mime_type_arr = array('image/gif','image/jpeg','image/pjpeg','image/png','image/x-png');
$mime = mime_content_type($_FILES['profile_image']['tmp_name']);
if(isset($_FILES['profile_image']['tmp_name']) && $_FILES['profile_image']['tmp_name']!="")
{
if(in_array($mime, $allowed_mime_type_arr))
{
return true;
} else {
$this->form_validation->set_message('file_check', 'Please select only jpg/jpeg/png file.');
return false;
}
}else{
$this->form_validation->set_message('file_check', 'Please choose a file to upload.');
return false;
}
}
So my upload function will look like this
if($this->form_validation->run() == true) {
if (!$this->upload->do_upload('profile_image')) {
return $this->response(['msg'=>$this->upload->display_errors(),'success'=>false,'code'=>400]);
} else {
$fileName = $this->upload->data();
$name = $fileName['file_name'];
}
//Save into database
$image = $this->Api_model->update_profile_image('assets/uploads/profile_images/'.$name, $request_data['user_id']);
if($image)
return $this->response(['msg'=>'Image updated successfully','success'=>true,'code'=>200, 'image_path' => base_url().$image]);
else
return $this->response(['msg'=>'Image updated failed','success'=>false,'code'=>400]);
} else {
return $this->response(['msg' => validation_errors(), 'success' => false, 'code' => 401]);
}
I am trying to use Symfony forms to handle REST requests.
I was facing issue with binding request data in symfony form. While going through Symfony's code, I found it uses
HttpFoundationRequestHandler->handleRequest
In that, for POST,
if ('' === $name) {
$params = $request->request->all();
$files = $request->files->all();
} elseif ($request->request->has($name) || $request->files->has($name)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = $request->request->get($name, $default);
$files = $request->files->get($name, $default);
} else {
// Don't submit the form if it is not present in the request
return;
}
If you see above code, if there is form name in Our form type class, it tries to get values from request as
$request->request->get($name) // $name is form name.
This may work if we render form as HTML but if we post request through REST, it doesnt find data.
To make it work we either have to namespace it like below in request (I haven't tested personally this but have read it somewhere)
{
'form_name': {
'field1' => 'value1'
}
}
Only below requst doesnt't bind data
{
'field1' => 'value1'
}
or we will have to return form name as null from getName from form type so that it use root namespace.
public function getName()
{
return null;
}
If we return null, then it creates other problem, if there are any extra parameters in request other than form fields it gives validation errors.
"This form should not contain extra fields."
Ideally form should just fetch the feild values from request which are configured in form and should ignore any other request parameters which are unknowne to it.
e.g. if this is the form
class SampleFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('field1', 'text', array('constraints' => new NotBlank()))
->add('field2', 'password', array('constraints' => new NotBlank()));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'csrf_protection' => false,
));
}
public function getName()
{
return null;
}
}
but in request if I am sending
{
'field1' => 'value1',
'field2' => 'value2',
'field3' => 'value3'
}
It gives above validation errors. It should ideally simply ignore field3 and fetch feild1 & field2 from request.
If we compare code in NativeRequestHandler & HttpFoundationRequestHandler,
NativeRequestHandler seem to have handled it properly
if ('' === $name) {
$params = $_POST;
$files = $fixedFiles;
} elseif (array_key_exists($name, $_POST) || array_key_exists($name, $fixedFiles)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = array_key_exists($name, $_POST) ? $_POST[$name] : $default;
$files = array_key_exists($name, $fixedFiles) ? $fixedFiles[$name] : $default;
} else {
// Don't submit the form if it is not present in the request
return;
}
where as HttpFoundationRequestHandler doesn't
if ('' === $name) {
$params = $request->request->all();
$files = $request->files->all();
} elseif ($request->request->has($name) || $request->files->has($name)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = $request->request->get($name, $default);
$files = $request->files->get($name, $default);
} else {
// Don't submit the form if it is not present in the request
return;
}
So either we need to be able to use NativeRequestHandler or we need fix in HttpFoundationRequestHandler ?
I see below works though only in case of content-type text request (doesnt work with application/json),
$form->submit(array('field1' => $request->request->get('field1'), 'field2' => $request->request->get('field2')))
But using $form->handleRequest($request) looks more simpler and abstract.
If there is any other better and simpler solution please do suggest.
I am implementing an updatePasswordAction and its not displaying an error with an invalid current password. I could not implement this with a Zend_Validate class to use with a supplied record->password, so i just validated for now in my controller action and if failed then i add the error message to the form element. this is just before i run $form->isValid. In any case, its working. but when the validation fails, its not displaying the error message on this on the element. any help would be greatly appreciated.
FYI: When I submit a blank current password, it shows the validation
class Admin_Form_UserPassword extends Katana_Form
{
public function init()
{
$element = $this->createElement('hidden', 'id');
$this->addElement($element);
$element = $this->createElement('password','password');
$element->setLabel('Current Password:');
$element->setRequired(true);
$this->addElement($element);
$element = $this->createElement('password','new_password');
$element->setLabel('New Password:');
$element->addValidator('StringLength', false, array(6,24));
$element->setRequired(true);
$element->addValidator('NotEmpty');
$this->addElement($element);
$element = $this->createElement('password','new_password_confirm');
$element->setLabel('Confirm:');
$element->addValidator('StringLength', false, array(6,24));
$element->addValidator('IdenticalField', false, array('new_password', 'Confirm Password'));
$element->setRequired(true);
$this->addElement($element);
$this->addElement('submit', 'submit', array('label' => 'Submit'));
}
}
public function updatePasswordAction()
{
$resourceModel = new Core_Model_Resource_User();
$form = new Admin_Form_UserPassword();
$form->setMethod(Katana_Form::METHOD_POST);
$form->setAction($this->getActionUrl('update-password'));
if($this->getRequest()->isPost()){
$id = $this->getRequest()->getParam('id');
$record = $resourceModel->find($id)->current();
$currPassword = $record->password;
$typedPassword = md5($this->getRequest()->getParam('password'));
if($currPassword !== $typedPassword){
$form->getElement('password')->addError('Current password is incorrect.');
}
if($form->isValid($_POST)){
$data = $form->getValues();
$result = $resourceModel->updatePassword($id, $data['new_password']);
if($result){
$this->redirectSimple('list');
}
}
} else {
$id = $this->getRequest()->getParam('id');
$recordData = array(
'id' => $id
);
$form->populate($recordData);
}
$this->getView()->form = $form;
}
Adding an error to the element doesn't cause the form itself to then be invalid.
There are at least 2 methods I use to get around this:
if($currPassword !== $typedPassword){
$form->getElement('password')->addError('Current password is incorrect.');
$form->markAsError();
}
// or
if ($form->isValid($_POST) && 0 == sizeof($form->getMessages()) {
// form was valid, and no errors were set on elements
}
To clarify, when you add the error to the form ELEMENT, there is an error attached to that element, but Zend_Form::isValid only runs the validators and sets appropriate errors, it doesn't check to see if you had set an error on a particular element.
You can however call $form->getMessages() to get all the error messages attached to the form or its child elements. If this is 0 and you have validated your form, then it means there were no errors. If your form passed isValid but you added an error to an element, it will include the error message you added.
I made it work this way.
Controller:
if ($trial->getKind() != 'debt' && $_POST['kind'] == 'debt')
{
$editForm->getElement('kind')->markAsError();
}
if ($editForm->isValid($_POST)) { ... }
Form:
public function isValid($data)
{
$valid = parent::isValid($data);
if ($this->getElement('kind')->hasErrors()) {
$this->getElement('kind')->addError($this->_translate->translate('You can\'t change trial kind to debt.'));
$valid = false;
}
return $valid;
}
And this comment helped me.
i'm trying to setup a codeigniter form with different error messages.
set_message(rule, msg) is setting up a message for the whole form.
I need:
$this->form_validation->set_rules('name', 'First Name', 'required');
$this->form_validation->set_message('name', 'required', 'Enter your Name');
$this->form_validation->set_rules('second', 'Variables', 'required');
$this->form_validation->set_message('second', 'required',
'The Variables are required');
Adding the %s into the message string is no help in this case, since the messages have to be completely different.
Possibly I could do something like:
controller
$this->form_validation->set_rules('name', 'Name',
'required|min_length[6]|max_length[12]');
$this->form_validation->set_rules('second', 'Variables',
'required|min_length[3]|max_length[5]');
$this->form_validation->set_message('required', 'required');
$this->form_validation->set_message('min_length', 'short');
$this->form_validation->set_message('max_length', 'long');
view
switch(form_error('name')) {
case '<p>required</p>':
echo 'Enter your Name';
break;
case '<p>short</p>':
echo 'min length 6';
break;
case '<p>long</p>':
echo 'min length 12';
break;
}
switch(form_error('second')) {
case '<p>required</p>':
echo 'The Variables are required';
break;
case '<p>short</p>':
echo 'min length 3';
break;
case '<p>long</p>':
echo 'min length 5';
break;
}
But isn't there a smarter way to do it?
I think a smarter way would be to use Codeigniter's callback feature (something similar to below). The following works but it may be possible to streamline it even more. If nothing else, it's a starting point.
Create two callback functions (I've named these custom_required and custom_check_length) and place them at the bottom of your controller (or wherever you feel necessary).
private function _custom_required($str, $func) {
switch($func) {
case 'name':
$this->form_validation->set_message('custom_required', 'Enter your name');
return (trim($str) == '') ? FALSE : TRUE;
break;
case 'second':
$this->form_validation->set_message('custom_required', 'The variables are required');
return (trim($str) == '') ? FALSE : TRUE;
break;
}
}
and...
private function _custom_check_length($str, $params) {
$val = explode(',', $params);
$min = $val[0];
$max = $val[1];
if(strlen($str) <= $max && strlen($str) >= $min) {
return TRUE;
} elseif(strlen($str) < $min) {
$this->form_validation->set_message('custom_check_length', 'Min length ' . $min);
return FALSE;
} elseif(strlen($str) > $max) {
$this->form_validation->set_message('custom_check_length', 'Max length ' . $max);
return FALSE;
}
}
These two functions take care of the set_message aspect of your form validation. To set the rules, you simply need to call these two functions by prefixing the function name with callback_.
So...
$this->form_validation->set_rules('name', 'Name', 'callback__custom_required[name]|callback__custom_check_length[6,12]');
$this->form_validation->set_rules('second', 'Second', 'callback__custom_required[second]|callback__custom_check_length[3,5]');
I hope the above helps in some way!!
you can set custom error like I mentioned below, no need to create custom function for this error message content change.
$validation = array(
array(
'field' => 'name',
'label' => 'NAME',
'rules' => 'trim|required',
"errors" => array('required' => " Enter your %s. ")
),
);
$this->form_validation->set_rules($validation);
if ($this->form_validation->run()) {}
You were almost there with your initial thought. All you needed was to execute validation after each group of set_message() changes. I find this approach much easier and faster than callback functions, unless you are going to use this exact customisation in many places.
$this->form_validation->set_rules('name', 'First Name', 'required|alpha')
$this->form_validation->set_message('name', 'required', 'Enter your Name');
$this->form_validation->set_message('name', 'alpha', 'Numbers in %s?');
$this->form_validation->run();
$this->form_validation->set_rules('second', 'Variables', 'required');
$this->form_validation->set_message('second', 'required', 'Variables required');
if ($this->form_validation->run()) {
...
}
This validation approach works on all versions of Codeigniter.
$this->form_validation->set_rules('name', 'Name', 'callback__custom_required[name]|callback__custom_check_length[6,12]');
$this->form_validation->set_rules('second', 'Second', 'callback__custom_required[second]|callback__custom_check_length[3,5]');**