I am using codeigniter. I am currently having a very simple form (nothing but input fields) that submits to the controller for processing.
That all doesn't matter, but what I am asking about is that I have an upload file in the form also. so the upload function will check for file size and type and so on and gives error if not complying. when that happens and I choose another file that matches the requirement, I submit but nothing goes to next page but the uploaded file and its details while the other fields are not posted or are blank.
It is as if the post is not cached and when I select new file to upload and its okay, it checks $_POST of those fields and they are empty. How can I check for that so that to make sure all fields contain values?
Thank you and more than happy to help elaborating.
To repopulate the fields you can use the set_value function.
set_value()
Permits you to set the value of an input form or textarea. You must supply the field name via the first parameter of the function. The second (optional) parameter allows you to set a default value for the form.
First you check if the form validation and upload was successful.
If both are successful we redirect the user to a new page.
If one of these is unsuccessful we add the error message to your data array which we can access in our view and display our form.
Controller
public function signup()
{
// Data array
$data = array();
// Load form validation libary
$this->load->library('form_validation');
// Load upload library and set configuration
$config['upload_path'] = './uploads/';
$this->load->library('upload', $config);
// Set the required fields
$this->form_validation->set_rules('first_name', 'First name', 'required');
if ($this->form_validation->run() == TRUE)
{
// If upload was succesfull
if ($this->upload->do_upload())
{
$upload_data = $this->upload->data();
// Build array to store in database
$save_data = array(
'first_name' => $this->input->post('first_name'),
'image' => $upload_data['file_name']
);
// Send data to your model to process
$this->your_model->save($save_data);
// Redirect to success page
redirect('registration_succes');
}
else
{
// Upload failed, set error
$data['error'] = $this->upload->display_errors();
}
}
else
{
// Form validation failed, set error
$data['error'] = validation_errors();
}
// Display the form by default or on error
$this->load->view('myform', $data);
}
In our view we repopulate the fields with the submitted values using the set_value function.
View ( myform )
<?php echo form_open_multipart('signup');?>
<fieldset>
<?php if( isset($error) && ! empty($error) ): ?>
<div class="error"><?php echo $error; ?></div>
<?php endif; ?>
<p>
<label>First name</label>
<input type="text" name="first_name" value="<?php echo set_value('first_name'); ?>" />
</p>
<p>
<label>File</label>
<input type="file" name="userfile" size="20" />
</p>
<p>
<input type="submit" />
</p>
</fieldset>
</form>
Related
I have a series of forms on a page in relation to image uploads. I have some PHP validations that happen and I would like to have the error message outputted at the top of the individual form instance that fails the validation.
I've noticed other questions on here with this issue but they are instances where the name of a hidden form element is essentially hard-coded.
A user of the site in the code below can upload up to 10 images so there will be up to 10 instances of the form on the page which are outputted via a while loop.
In the following code I have a filename variable in the hidden input element (this filename is assigned when the image is initially uploaded via the Imagick PHP library). At the top of each form I have a foreach loop that echos out the failed validation message (in the code below I've only included one validation) and hence would like the error message to apply to the particular form instance which has the error.
Here is an example of some of the information submitted including a sample PHP validation:
<?php
if(isset($_POST['upload-submit'])) {
$image_title = $_POST['image-title'];
$image_tags = $_POST['image-tags'];
$form_filename = $_POST['image-filename']; // hidden form element
$image_title = filter_var($image_title, FILTER_SANITIZE_STRING);
$image_tags = filter_var($image_tags, FILTER_SANITIZE_STRING);
$form_filename = filter_var($form_filename, FILTER_SANITIZE_STRING);
// example of form validation
if(empty(trim($image_title))){
$error[] = "Image Title cannot be blank";
}
if (!isset($error)) {
try {
$sql = "UPDATE imageposts SET
image_title = :image_title,
image_tags = :image_tags
WHERE filename = :filename";
$stmt = $connection->prepare($sql);
$stmt->execute([
':image_title' => $image_title,
':image_tags' => $image_tags,
':filename' => $form_filename
]);
} catch (PDOException $e) {
echo "Error: " . $e->getMessage(); // this is for PDO errors not validation errors
}
} else {
// give values an empty string to avoid an error being thrown before form submission if empty
$image_title = $image_tags = "";
}
}
?>
Simplified version of how the form instances are outputted on to the page:
<?php
// $user_id is assigned via a $_SESSION when user logs in
$stmt = $connection->prepare("SELECT * FROM imageposts WHERE user_id = :user_id");
$stmt->execute([
':user_id' => $user_id
]);
while ($row = $stmt->fetch()) {
$db_image_filename = escape($row['filename']); // outputted into the value attribute of the hidden input element
?>
<form method="post" enctype="multipart/form-data">
<?php
// -- echo error messages at top of the form
if(isset($error)) {
foreach($error as $msg) {
echo "<p>* ERROR: {$msg}</p>";
}
}
?>
<div>
<div class="form-row">
<label for="upload-details-title">Image Title</label>
<input id="upload-details-title" type="text" name="image-title">
</div>
<div class="form-row">
<label for="upload-details-tags">Comma Separated Image Tags</label>
<textarea id="upload-details-tags" type="text" name="image-tags"></textarea>
</div>
<div class="form-row">
<button name="upload-submit">COMPLETE UPLOAD</button>
</div>
<div class="form-row">
<!-- hidden form input -->
<input type="hidden" name="image-filename" value="<?php echo $db_image_filename; ?>">
</div>
</div>
</form>
<?php } ?>
How do get it so the form instance with the error is the only one that shows the error message ?
You will need something that allows you to identify your form instances in the first place, and you need to submit it together with the rest of the fields, so that you have the info which form the submission came from, available at that point where you do your validation.
Since apparently the image filename itself can be used to identify the form it is in here, you don't need to create & send anything extra. Just check if $form_filename === $db_image_filename before you output the error messages inside the form inside within the while loop.
You can put both that and the check whether $errors is even set, into the same if:
<form method="post" enctype="multipart/form-data">
<?php
// -- echo error messages at top of the form
if($form_filename === $db_image_filename && isset($error)) {
foreach($error as $msg) {
echo "<p>* ERROR: {$msg}</p>";
}
}
?>
I have a website based on codeigniter framework. I have a form on my index page and some prices of flights which are coming through my database.
here is my form:
<?php echo validation_errors(); ?>
<form action="<?php echo base_url() ?>detail/travel" method="post">
<input type="text" name="departure">
<input type="text" name="destination">
<input type="text" name="name">
<input type="text" name="cell">
</form>
so my problem is when user did not fill the whole form and submit the button, it goes into the function of "travel" which I made in my controller(detail) and show 0 results because of the error. I want that user remain on my index page with all the details until he fill the form correctly and show errors on my index page if he missed any field of my form.
here is my function "travel" that i have in my controller(detail):
function search_travel(){
if($_POST){
$config = array(
array(
'field'=>'departure',
'label'=>'departure',
'rules'=>'trim|required|alpha'
),
array(
'field'=>'destination',
'label'=>'destination',
'rules'=>'trim|required|alpha'
),
array(
'field'=>'name',
'label'=>'name',
'rules'=>'trim|required|alpha'
),
array(
'field'=>'cell',
'label'=>'cell no',
'rules'=>'trim|required|regex_match[/^[0-13]+$/]'
)
);
$this->load->library('form_validation');
$this->load->helper(array('form', 'url'));
$this->form_validation->set_rules($config);
if($this->form_validation->run() == FALSE){
$data['errors']= validation_errors();
}
else{
$destination= $this->input->post('destination');
$this->email->send();
$data['var']= $this->Travel->search_travel($destination);
$this->load->view('details',$data)
}
}
}
and my index function is:
function index(){
$data['fares']= $this->Travel->all_fares();
$this->load->view('index', $data);
}
you need to redirect to old page and print error in view page
<?php echo form_error('departure'); ?>
(print this in view for each input fields and below in controller)
if ($this->form_validation->run() == FALSE) {
redirect('method name that loads form');
}
I'm using codeigniter for my project and I need to read contents of files. So,I need validation to check whether the file is selected or not.
Here is my code in controller
$this->form_validation->set_rules(
'estimation_file',
'Project Estimation File',
'required'
);
But while choosing a file it shows error saying - The Project
Estimation File field is required
In codeigniter you cannot check the validation of two dimension array or file field with form_validation, instead you can check it after posting the data.
$this->form_validation->set_rules('validation_check','any required field','required');
if($this->form_validation->run()==FALSE)
{
// your code before posting...
}
else
{
// check the file posting
if($_FILES['estimation_file']['name']!='')
{
// if file selected or not empty
}
else
{
// if file not selected | empty | redirect
}
}
do not forget to write enctype="multipart/form-data" within the form field, otherwise your file field will not pass the value of two dimension array.
<form method="post" enctype="multipart/form-data" name="upload_form" action="">
<input type="hidden" name="validation_check" value="TRUE" />
<input type="file" name="estimation_file" value="" />
<input type="submit" value="Post" />
</form>
public function edit_profile(){
$logged_in_user = $this->session->userdata('logged_in');
$data['images_url'] = $this->config->item('images_url');
$data['cdn_url'] = $this->config->item('cdn_url');
$data['reminder'] = $this->config->item('reminder');
$data['current_module'] = "ess";
$data['user_details'] = $this->ess->get_user_details($logged_in_user['user_id']);
$this->load->view("header", $data);
$this->load->view("leftbar", $data);
$this->load->view("ess/ess_edit_profile");
$this->load->view("footer", $data);
if($this->input->post('submit')){
$post_data = $this->input->post();
$this->form_validation->set_rules('full_name','Full Name','required|trim|xss_clean');
$this->form_validation->set_rules('email','Email','required|trim|valid_email');
$this->form_validation->set_rules('blood_group','Blood Group','max_length[2]');
$this->form_validation->set_rules('phone','Phone','required|trim|xss_clean');
$this->form_validation->set_rules('address','Address','required|xss_clean|max_length[100]');
$this->form_validation->set_rules('designation','Designation','required|xss_clean');
$this->form_validation->set_rules('emergency_name','Emergency Name','required|xss_clean');
$this->form_validation->set_rules('emergency_number','Emergency Number','required|xss_clean');
$this->form_validation->set_rules('next_of_kin','Next of Kin','trim|xss_clean');
if($this->form_validation->run() === true){
// update data
} else {
$this->load->view("ess/ess_edit_profile");
}
}
}
Above is the function of my controller that loads a edit profile view with database populated values in input fields. Now when the form get submitted after doing editing it goes to validation process in edit_profile() function. I am deliberately running false the validation function for checking purpose. Now if the validation runs === false i loaded the ess_edit_profile view again but the validation messages are not appearing. Also the form fields are getting populated with default values which i've set via set_value() function
Below is how i am showing form fields with database data
<td>
<label for="full_name">Full Name</label>
<input style="width: 300px;" type="text" name="full_name" id="full_name" value="<?php echo set_value('full_name',$user_details[0]->ui_full_name); ?>" />
<?php echo form_error('full_name', '<span class="alert">', '</span>'); ?>
</td>
try this remove else part then try
if($this->form_validation->run() === true){
// update data
}
$this->load->view("ess/ess_edit_profile");
Please use set_value function to set element values
Like this
<input type="text" name="name" value="<?php echo set_value("name", $database_name)?>"/>
In Controller
$this->form_validation->set_rules('name','Edit name','trim|xss_clean|required');
If the value not required then also set validation rules trim
$this->form_validation->set_rules('name','Edit name','trim');
How do you use the email->attach function?
I can't figure what is happen, cos when i put the code for email->attach the mesage came in blank(the mail body) and there is no attach.
If i remove that code line, everything come back to normal..
thank you
my controller (sendmail.php)
<?php
class Sendmail extends Controller {
function __construct() {
parent::Controller();
$this->load->library('email');
$this->load->helper('url');
$this->load->helper('form');
$this->load->library('validation');
}
function index() {
$info = array (
'nome' => $this->input->post('nome'),
'mail' => $this->input->post('email'),
'motivo' => $this->input->post('motivo'),
'mensagem' => $this->input->post('mensagem'),
'anexo' => $this->input->post('upload'),
);
$this->load->library('email');
$this->email->set_newline('\r\n');
$this->email->clear();
$this->email->from($info['mail'], $info['nome']);
$this->email->to('example#mai.com');
/* $this->email->cc(''); # não é preciso */
$this->email->subject($info['motivo']);
$this->email->message($info['mensagem']);
$this->email->attach($info['anexo']);
if ($this->email->send() ) {
echo 'sent';
}
else {
$this->load->view('formulario');
# show_error( $this->email->print_debugger() );
}
}
}
?>
my view (formulario.php)
<?php
echo form_open_multipart('davidslv/index.php/sendmail');
?>
<label for="nome">nome</label>
<input type="text" name="nome" id="nome" required />
<label for="email">email</label>
<input type="text" name="email" id="email" required />
<label for="assunto">assunto</label>
<select name="motivo">
<option value="motivo1">motivo1</option>
<option value="motivo2">motivo2</option>
<option value="motivo3">motivo3</option>
</select>
<p> <label for="mensagem">mensagem</label>
<textarea name="mensagem" id="mensagem" rows="8" cols="30" required></textarea>
</p>
<label for="upload">documento</label>
<input type="file" id="upload" name="upload" size="18"/>
<input type="submit" id="enviar" name="enviar" value="Enviar!" />
</form>
You can not directly attach a file from the upload field of your form to an email. You can only attach files to your email from your server, so you need to upload the file from the form with CIs upload library: $this->upload->do_upload() to your server into some directory. the upload library needs to be configured, which file types are allowed etc. if the upload was successful, the do_upload function returns extensive data about where the file is stored. you can use the 'full_path' index from the array to attach this file to the email. then send the mail. after that you may delete the file from your server. Here are some code fragments that might help.
$this->load->library('upload');
if($_FILES['upload']['size'] > 0) { // upload is the name of the file field in the form
$aConfig['upload_path'] = '/someUploadDir/';
$aConfig['allowed_types'] = 'doc|docx|pdf|jpg|png';
$aConfig['max_size'] = '3000';
$aConfig['max_width'] = '1280';
$aConfig['max_height'] = '1024';
$this->upload->initialize($aConfig);
if($this->upload->do_upload('upload'))
{
$ret = $this->upload->data();
} else {
...
}
$pathToUploadedFile = $ret['full_path'];
$this->email->attach($pathToUploadedFile);
...
$this->email->send();
...
}
...
Hope this helped...
$this->email->attach()
Enables you to send an attachment. Put
the file path/name in the first
parameter. Note: Use a file path, not
a URL. For multiple attachments use
the function multiple times. For
example:
$this->email->attach('/path/to/photo1.jpg');
$this->email->attach('/path/to/photo2.jpg');
$this->email->attach('/path/to/photo3.jpg');
$this->email->send();
Codeigniter Email Class
This is Absolutely right code Please Try
$config['upload_path'] = './uploads';
$config['allowed_types'] = 'gif|jpg|jpeg|png|txt|php|pdf';
$config['max_size'] = '9000';
$config['encrypt_name'] = true;
$image_data = $this->upload->data();
$fname=$image_data[file_name];
$fpath=$image_data[file_path].$fname;
$this->email->attach($fpath);
step 1:You can not directly attach a file from the upload field of your form to an email. You can only attach files to your email from your server, so you need to upload the file from the form with CIs upload library:
$this->upload->do_upload() to your server into some directory.
step 2:
$file=upload file;
$file_path='uploaded directory on your server(eg:uploads/career)'.$file;
step 3:just include
$this->email->attach($file_path);
$this->email->send();
This is a late update, but it might be useful.
It was said twice
"You can not directly attach a file from the upload field of your form
to an email"
. However, this works fine in Codeigniter 3.0
foreach ($_FILES as $key => $file)
{
if ($file['error'] == 0)
{
$this->email->attach($file['tmp_name'], '', $file['name']);
}
}
(Though, the email is not sent and no errors are shown, if there are two files with the same name)