Moorcam Posted February 17, 2023 Share Posted February 17, 2023 Hi guys, Trying to implement an import function in Codeigniter 3 but not working. There are no errors, just get this screen: An Error Was Encountered The action you have requested is not allowed. Here is the Controller part: public function importdata() { $this->load->view('view_fleet'); if(isset($_POST["submit"])) { $file = $_FILES['file']['tmp_name']; $handle = fopen($file, "r"); $c = 0;// while(($filesop = fgetcsv($handle, 1000, ",")) !== false) { $v_number = $filesop[0]; $v_eng_number = $filesop[1]; $v_vin = $filesop[2]; $v_chassis = $filesop[3]; $v_make = $filesop[4]; $v_model = $filesop[5]; $v_height = $filesop[6]; $v_length = $filesop[7]; $v_width = $filesop[8]; $v_reg = $filesop[9]; $v_pax = $filesop[10]; $tacho_number = $$filesop[11]; $service_date = $filesop[12]; $v_notes = $filesop[13]; $status = $filesop[14]; if($c<>0){ /* SKIP THE FIRST ROW */ $this->Model_fleet->saverecords( $v_number, $v_eng_number, $v_vin, $$v_chassis, $v_make, $v_model, $v_height, $v_length, $v_width, $v_reg, $v_pax, $tacho_number, $service_date, $v_notes, $status ); } $c = $c + 1; } echo "sucessfully import data !"; } } Now the Model part: function saverecords($v_number,$v_reg) { $query="insert into tbl_fleet values('$v_number','$v_eng_number','$v_vin','$v_chassis','$v_make','$v_model','$v_height','$v_length','$v_width','$v_reg','$v_pax','$tacho_number','$service_date','$v_notes,$status')"; $this->db->query($query); } And finally the View part: <label for="exampleInputFile">Upload Excel or CSV</label> <form enctype="multipart/form-data" method="post" role="form"> <div class="form-group"> <input type="file" name="file" id="file" size="150"> <p class="help-block">Only Excel/CSV File Import.</p> </div> <button type="submit" class="btn btn-default" name="submit" value="submit">Upload</button> </form> </div> Please note that the View section is infact in a Modal. Not sure if that's the issue? If anyone can help with this I will send you some Guinness. Thanks. Quote Link to comment Share on other sites More sharing options...
requinix Posted February 17, 2023 Share Posted February 17, 2023 Do you need to include a CSRF token in your form? Quote Link to comment Share on other sites More sharing options...
Moorcam Posted February 17, 2023 Author Share Posted February 17, 2023 11 minutes ago, requinix said: Do you need to include a CSRF token in your form? Thank you. That sorted the above error out. Now, no data being imported. Quote Link to comment Share on other sites More sharing options...
maxxd Posted February 17, 2023 Share Posted February 17, 2023 It's been a few years since I used CodeIgniter, but it certainly looks like you're passing 15 parameters (one of which is a dynamic variable) to a method that accepts 2 parameters. If you try to dump anything other than $v_number or $v_reg from your save_records() method, what do you get? Quote Link to comment Share on other sites More sharing options...
Moorcam Posted February 17, 2023 Author Share Posted February 17, 2023 18 minutes ago, maxxd said: It's been a few years since I used CodeIgniter, but it certainly looks like you're passing 15 parameters (one of which is a dynamic variable) to a method that accepts 2 parameters. If you try to dump anything other than $v_number or $v_reg from your save_records() method, what do you get? Same thing. I also sorted the 15 against the 2 variables (missed that) and also still the same. Quote Link to comment Share on other sites More sharing options...
maxxd Posted February 17, 2023 Share Posted February 17, 2023 I kinda feel like you need to load the model and tell it to connect to the database before you try to do anything with it? I think the last time I worked with CI was like 3 years ago? It was slightly before the onset of covid, so I may be completely wrong. Quote Link to comment Share on other sites More sharing options...
Moorcam Posted February 17, 2023 Author Share Posted February 17, 2023 (edited) 28 minutes ago, maxxd said: I kinda feel like you need to load the model and tell it to connect to the database before you try to do anything with it? I think the last time I worked with CI was like 3 years ago? It was slightly before the onset of covid, so I may be completely wrong. Don't think so. I am already updating, adding, deleting data from that same Model. I have also modified the Model code for the saverecords so it is similar to others I am using: function saverecords($v_number,$v_eng_number,$v_vin,$v_chassis,$v_make,$v_model,$v_height,$v_length,$v_width,$v_reg,$v_pax,$tacho_number,$service_date,$v_notes,$status) { $this->db->insert('tbl_fleet',$v_number,$v_eng_number,$v_vin,$v_chassis,$v_make,$v_model,$v_height,$v_length,$v_width,$v_reg,$v_pax,$tacho_number,$service_date,$v_notes,$status); return $this->db->insert_id(); } My feeling is it is with the controller part posted below. I am just at a complete loss with it. public function importdata() { $this->load->view('view_fleet'); if(isset($_POST["submit"])) { $file = $_FILES['file']['tmp_name']; $handle = fopen($file, "r"); $c = 0;// while(($filesop = fgetcsv($handle, 1000, ",")) !== false) { $v_number = $filesop[0]; $v_eng_number = $filesop[1]; $v_vin = $filesop[2]; $v_chassis = $filesop[3]; $v_make = $filesop[4]; $v_model = $filesop[5]; $v_height = $filesop[6]; $v_length = $filesop[7]; $v_width = $filesop[8]; $v_reg = $filesop[9]; $v_pax = $filesop[10]; $tacho_number = $$filesop[11]; $service_date = $filesop[12]; $v_notes = $filesop[13]; $status = $filesop[14]; if($c<>0){ /* SKIP THE FIRST ROW */ $this->Model_fleet->saverecords( $v_number, $v_eng_number, $v_vin, $$v_chassis, $v_make, $v_model, $v_height, $v_length, $v_width, $v_reg, $v_pax, $tacho_number, $service_date, $v_notes, $status ); } $c = $c + 1; } echo "sucessfully import data !"; }else{ $this->session->set_flashdata('error',$error); redirect(base_url().'admin/fleet/edit/'.$id); } } Edited February 17, 2023 by Moorcam Quote Link to comment Share on other sites More sharing options...
maxxd Posted February 17, 2023 Share Posted February 17, 2023 From the documentation for db->insert: Quote The first parameter will contain the table name, the second is an associative array of values. Have you tried catching the return value from the method and echoing it out during the loop? Or even just echoing the values on each loop so you know that you're dealing with what you think you're dealing with? Quote Link to comment Share on other sites More sharing options...
Moorcam Posted February 18, 2023 Author Share Posted February 18, 2023 (edited) 1 hour ago, maxxd said: From the documentation for db->insert: Have you tried catching the return value from the method and echoing it out during the loop? Or even just echoing the values on each loop so you know that you're dealing with what you think you're dealing with? I am running this just after the success set_flashdata: echo "<pre>"; print_r($this->Model_fleet->saverecords); Nothing Edited February 18, 2023 by Moorcam Quote Link to comment Share on other sites More sharing options...
maxxd Posted February 18, 2023 Share Posted February 18, 2023 (edited) I don't see a set_flashback() on success - I also don't see you checking for success or failure on the insert; I see an else statement if $_POST['submit'] isn't set (which is kinda problematic as sometimes the button doesn't get passed along in post - I don't remember why or how, but best practice is to check the request method when processing a form) but the return value from your model method saverecords() is never checked. If insert_id() returns null or void then you can assume the insert failed. The other concern is that db->insert() takes two parameters - one string and one array - but you're passing 16 string parameters to it. That's one parameter that matches expected type, one parameter that doesn't match type, and 14 parameters that are ignored entirely. Edited February 18, 2023 by maxxd Quote Link to comment Share on other sites More sharing options...
Moorcam Posted February 18, 2023 Author Share Posted February 18, 2023 22 minutes ago, maxxd said: The other concern is that db->insert() takes two parameters - one string and one array - but you're passing 16 string parameters to it. That's one parameter that matches expected type, one parameter that doesn't match type, and 14 parameters that are ignored entirely. I have amended that in my last reply. I have tried other methods as well, uploading the file to /uploads/ and trying to read it from there. Can't even get the bloody thing to upload. I give up. Thanks anyway. Quote Link to comment Share on other sites More sharing options...
maxxd Posted February 18, 2023 Share Posted February 18, 2023 37 minutes ago, Moorcam said: I have amended that in my last reply. Where? You posted this: echo "<pre>"; print_r($this->Model_fleet->saverecords); This won't actually run the saverecords() method, and even if it did it's now passing no arguments instead of 15. Instead of passing all the individual properties of saverecords() to insert(), create an array of them and pass that to the db->insert() method. Before you do that, though, echo every row of the csv file to the browser to make sure your problem is with storage and not input. If the script can't find the input file it certainly won't be able to store the records to the database. Quote Link to comment Share on other sites More sharing options...
Moorcam Posted February 18, 2023 Author Share Posted February 18, 2023 1 hour ago, maxxd said: Where? You posted this: echo "<pre>"; print_r($this->Model_fleet->saverecords); This won't actually run the saverecords() method, and even if it did it's now passing no arguments instead of 15. Instead of passing all the individual properties of saverecords() to insert(), create an array of them and pass that to the db->insert() method. Before you do that, though, echo every row of the csv file to the browser to make sure your problem is with storage and not input. If the script can't find the input file it certainly won't be able to store the records to the database. Posted a few posts back, sorry. function saverecords($v_number,$v_eng_number,$v_vin,$v_chassis,$v_make,$v_model,$v_height,$v_length,$v_width,$v_reg,$v_pax,$tacho_number,$service_date,$v_notes,$status) { $this->db->insert('tbl_fleet',$v_number,$v_eng_number,$v_vin,$v_chassis,$v_make,$v_model,$v_height,$v_length,$v_width,$v_reg,$v_pax,$tacho_number,$service_date,$v_notes,$status); return $this->db->insert_id(); } Anyway, I have tried the following. It shows no result at all. public function import_data(){ if(isset($_POST['file'])) { $csv = $_FILES['file']['tmp_name']; $handle = fopen($csv,"r"); while (($row = fgetcsv($handle, 10000, ",")) != FALSE) { $num = count($data); echo "<p> $num fields in line $row: <br /></p>\n"; $row++; for ($c=0; $c < $num; $c++) { echo $data[$c] . "<br />\n"; } } fclose($handle); } } Quote Link to comment Share on other sites More sharing options...
Moorcam Posted February 19, 2023 Author Share Posted February 19, 2023 Hi again folks, This really has me. I have changed to another method of importing, which includes uploading the file to the server and then reading it. Unfortunately, it isn't even uploading. Why? It baffles me as I have other uploads, such as images etc working just fine. Here is the controller now: function importcsv() { $data['fleet'] = $this->Model_fleet->show(); $data['error'] = ''; //initialize image upload error array to empty $config['upload_path'] = './uploads/csv/'; $config['allowed_types'] = 'csv'; $config['max_size'] = '1000'; $this->load->library('upload', $config); // If upload failed, display error if (!$this->upload->do_upload()) { $data['error'] = $this->upload->display_errors(); $this->load->view('admin/fleet', $data); } else { $file_data = $this->upload->data(); $file_path = $file_data['./uploads/csv/']; if ($this->Csvimport->get_array($file_path)) { $csv_array = $this->Csvimport->get_array($file_path); foreach ($csv_array as $row) { $insert_data = array( 'v_number'=>$row['v_number'], 'v_eng_number'=>$row['v_eng_number'], 'v_vin'=>$row['v_vin'], 'v_chassis'=>$row['v_chassis'], 'v_make'=>$row['v_make'], 'v_model'=>$row['v_model'], 'v_height'=>$row['v_height'], 'v_length'=>$row['v_length'], 'v_width'=>$row['v_width'], 'v_reg'=>$row['v_reg'], 'v_pax'=>$row['v_pax'], 'tacho_number'=>$row['tacho_number'], 'service_date'=>$row['service_date'], 'v_notes'=>$row['v_notes'], 'status'=>$row['status'], ); $this->Model_fleet->insert_csv($insert_data); } $this->session->set_flashdata('success', 'Csv Data Imported Succesfully'); redirect(base_url().'csv'); echo "<pre>"; print_r($insert_data); } else $data['error'] = "Error occured"; $this->load->view('admin/fleet', $data); } } Here is the Model: function insert_csv($data) { $this->db->insert('tbl_fleet', $data); } And the form (view): <!-- Modal Start --> <div class="modal fade" id="myModalDetail" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog" style="width:900px;"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title" id="myModalLabel"> Import Fleet </h4> </div> <div class="modal-body"> <div class="form-group"> <h3>Upload Fleet</h3> <h4>From the options below, you can simply import your fleet quickly by uploading a spreadsheet/</h4> <label for="exampleInputFile">Upload Excel or CSV</label> <?php echo form_open_multipart(base_url().'admin/fleet',array('class' => 'form-horizontal')); ?> <input type="file" name="file" ><br><br> <input type="submit" name="submit" value="UPLOAD" class="btn btn-primary"> <?php echo form_close(); ?> </div> </div> </div> </div> </div> <!-- Modal End --> I am also using the csvimport Library as below, which is saved in libraries/Csvimport.php <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * CodeIgniter CSV Import Class * * This library will help import a CSV file into * an associative array. * * This library treats the first row of a CSV file * as a column header row. * * * @package CodeIgniter * @subpackage Libraries * @category Libraries * @author Brad Stinson */ class Csvimport { private $filepath = ""; private $handle = ""; private $column_headers = array(); /** * Function that parses a CSV file and returns results * as an array. * * @access public * @param filepath string Location of the CSV file * @param column_headers array Alternate values that will be used for array keys instead of first line of CSV * @param detect_line_endings boolean When true sets the php INI settings to allow script to detect line endings. Needed for CSV files created on Macs. * @return array */ public function get_array($filepath='', $column_headers='', $detect_line_endings=FALSE) { global $column_headers; // If true, auto detect row endings if($detect_line_endings){ ini_set("auto_detect_line_endings", TRUE); } // If file exists, set filepath if(file_exists($filepath)) { $this->_set_filepath($filepath); } else { return FALSE; } // If column headers provided, set them $this->_set_column_headers($column_headers); // Open the CSV for reading $this->_get_handle(); $row = 0; while (($data = fgetcsv($this->handle, 0, ",")) !== FALSE) { // If first row, parse for column_headers if($row == 0) { // If column_headers already provided, use them if($this->column_headers) { foreach ($this->column_headers as $key => $value) { $column_headers[$key] = trim($value); } } else // Parse first row for column_headers to use { foreach ($data as $key => $value) { $column_headers[$key] = trim($value); } } } else { $new_row = $row - 1; // needed so that the returned array starts at 0 instead of 1 foreach($column_headers as $key => $value) // assumes there are as many columns as their are title columns { $result[$new_row][$value] = trim($data[$key]); } } $row++; } $this->_close_csv(); return $result; } /** * Sets the filepath of a given CSV file * * @access private * @param filepath string Location of the CSV file * @return void */ private function _set_filepath($filepath) { $this->filepath = $filepath; } /** * Sets the alternate column headers that will be used when creating the array * * @access private * @param column_headers array Alternate column_headers that will be used instead of first line of CSV * @return void */ private function _set_column_headers($column_headers='') { if(is_array($column_headers) && !empty($column_headers)) { $this->column_headers = $column_headers; } } /** * Opens the CSV file for parsing * * @access private * @return void */ private function _get_handle() { $this->handle = fopen($this->filepath, "r"); } /** * Closes the CSV file when complete * * @access private * @return array */ private function _close_csv() { fclose($this->handle); } } If anyone can please provide any idea I would love you forever. There are no errors etc, just nothing happening. Cheers, Dan Quote Link to comment Share on other sites More sharing options...
Solution Moorcam Posted August 27, 2023 Author Solution Share Posted August 27, 2023 Hi again all, Posting this for anyone who has experienced similar. It appears Codeigniter 3 has a bug that does not check for file extensions. Thus, not allowing certain files to be uploaded. The workaround is to create a piece of code that will do the checking for us and allow for it to be uploaded. Here is that little piece of code: $ext = strtolower(pathinfo($_FILES['userfile']['name'], PATHINFO_EXTENSION)); if ($ext != "csv") { // Not a CSV file - send error $this->session->set_flashdata('error', 'Incorrect file extension uploaded. Only .CSV allowed!'); redirect("admin/csv"); } Works a charm, thanks to my good friend Craig. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.