I am working on a codeigniter project. In the image upload config I have it as encrypted to allow unique file names to avoid overwriting and doubling of name and for more security in general.
So on upload it will encrypt the image file name, and store the encrypted name in the database while saving the image in my assets folder. But for some reason it doesn't seem to encrypt the image names at all. Almost like it is completely ignoring the $config options and just uploading the image.
Also I have attempted a call back function to avoid blank uploads and again seems that is ignored also and the post are still allowed.
If anyone can lend a tip. Please.
Controller
//Callback validation
$this->form_validation->set_rules('userfile','Photo','callback_photo_check');
if($this->form_validation->run() === FALSE){
$this->load->view('templates/header');
$this->load->view('posts/create', $data);
$this->load->view('templates/footer');
} else {
if($this->form_validation->run()==TRUE){
$config['upload_path'] = 'assets/images/posts';
$config['allowed_types'] = 'gif|jpg|jpeg';
$config['encrypt_name'] = TRUE; //TURN ON
$config['max_size'] = 0;
$config['max_width'] = 0;
$config['max_height'] = 0;
$this->upload->initialize($config);
if(!$this->upload->do_upload('userfile')){
$errors = array('error'=>$this->upload->display_errors());
$this->load->view('templates/header');
$this->load->view('posts/create', $errors);
$this->load->view('templates/footer');
}else {
$this->post_model->create_post($this->upload->data('full_path'),$this->input->post());
}
}
$this->session->set_flashdata('post_created','Your Post has been submitted');
redirect('posts');
}
}
public function photo_check(){
if(empty($_FILES['userfile'])){
$this->form_validation->set_message('photo_check', 'need a image');
return FALSE;
}
else{
return TRUE;
}
}
Model
public function create_post($path,$post){
$data = array(
'about'=> $this->input->post('Description'),
'image' => $path,
);
return $this->db->insert('posts',$data);
I have the same problem before, then I decided to give them(files) a unique name, what I did is:
• I assigned an empty variable which will hold the file name/ path data meant to be modified and I named it as $info_name.
• Everytime the file name will have a duplicate in the existing location it will add a unique extension such as time(seconds,date, etc).
Here is my sample code:
public function new_info($data,$photo){
extract($data);
$info_name = "";
$directory = "C:/xampp/htdocs/Parent folder/child folder/grand child folder/";
$extension= array("jpeg","jpg","png","gif");
$file_name=$photo["form_name"]["name"];
$file_tmp=$photo["form_name"]["tmp_name"];
$ext=pathinfo($file_name,PATHINFO_EXTENSION);
if(in_array($ext,$extension)){
if(!file_exists($directory.$file_name)){
move_uploaded_file($file_tmp=$photo["form_name"]["tmp_name"],$directory.$file_name);
$info_name = $file_name;
}
else{
$filename=basename($file_name,$ext);
$newFileName=$filename.time().".".$ext;
move_uploaded_file($file_tmp=$photo["form_name"]["tmp_name"],$directory.$newFileName);
$info_name = $newFileName;
}
}
// then your sql code here for example:
$data= array( 'user' => $_SESSION["user_id"],
'picture' => $info_name,
);
$this->db->insert('sys_post',$data);
}
To encrypt the uploaded file names, you have to follow below steps.
1) You have to load the Encryption Library.
You can call this library on particular page where there is upload code.
// LOAD LIBRARIES
$this->load->library('encryption');
OR you can also load it in autoload.php file in $autoload['libraries'] = array('database','form_validation','encryption');
2) Now you are using the Encryption class, you must set an encryption key in config.php file.
$config['encryption_key'] = 'your-own-encryption-key';
For more information regarding Encryption => https://codeigniter.com/user_guide/libraries/encryption.html
3) And finally, In your upload code $config['encrypt_name'] = TRUE;.
Hope this will help.
Related
I would like to replace and update uploaded Image using codeigniter. But I am not sure how to achieve that. Here is my below code -
MY CONTROLLER :
public function updateProccess()
{
$this->items_model->updateData();
if ($this->db->affected_rows() > 0) {
$this->session->set_flashdata('message', 'Update data is success');
}
redirect('items');
}
AND here's my model to update data
public function updateData()
{
$data = [
'barcode' => $this->input->post('barcode'),
'name' => $this->input->post('name'),
'categories_id' => $this->input->post('category'),
'units_id' => $this->input->post('unit'),
'price' => $this->input->post('price'),
'updated' => date('Y-m-d H:i:s')
];
$this->db->where('items_id', $this->input->post('items_id'));
$this->db->update('items', $data);
}
thank you for your help :)
This is my case:
Step 1: First I have checked file is not empty, if file is empty update file will not work, if file is uploaded from html then I have fetched previous record from database in a $row variable (temporary variables).
Step 2: After getting previous data, I have updated data in database i.e. path and name of new file.
Step 3: After that I have verified that user is updating data or inserting new one. If data is to be updated then old image will be deleted.
if($_FILES["img"]["name"]!="")
{
$row=$this->general_model->getSingle("banner", ["id"=>$id]);
$temp=$_FILES["img"]["name"];
$temp=explode(".", $temp);
$ext=end($temp);
$file_name_temp="banner".time().rand(0,9);
$file_name=$save["img"]=$file_name_temp.".".$ext;
$config["file_name"]=$file_name;
$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = 1024*10;
enter code here
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload('img'))
{`enter code here`
$msg=strip_tags($this->upload->display_errors());
_setFlashSession("msg", "<span class='label label-danger'>$msg</span>");
redirect("admin/site-configure/banner");
}
if($id!="")
{
$file="./uploads/".$row["img"];
unlink($file);
$file="./webp/".$row["webp"];
unlink($file);
}
}
I made a custom function before working with framework, that I want to use again now. the problem occurs when I tried uploading image with my custom function. it says error undefined index : [the field_name].
most people uses CI library and CI upload function do_upload() but I want to use my own function because it also creates smaller image to be used as thumb.
I started working with CI 3 days ago, and still don't know how to change anything that can make $_FILES[] working.
the view :
<form action="path/to/controller/method" method="post" enctype="multipart/form-data">
<input type="file" name="fupload">
</form>
the controller :
public function __construct(){
parent::__construct();
$this->load->helper('fungsi_thumb'); // this is the custom function
$config['allowed_types'] = '*';
$this->load->library('upload',$config);
}
public function input_file(){
$data = array(
'location_file' => $_FILES['fupload']['tmp_name'],
'type_file' => $_FILES['fupload']['type'],
'name_file' => $_FILES['fupload']['name']
);
$this->load->model('input_model');
$this->input_model->put_file($data);
}
I already put my custom function file in application\helpers\. Should I show the custom function file and the model file too?
I already change the public $allowed_types = '*'; too
UPDATE
the Model
public function put_file($data){
//BUAT FILE
$lokasi_file = $data['location_file'];
$tipe_file = $data['type_file'];
$nama_file = $data['name_file'];
$acak = rand(1,99);
$nama_file_unik = $acak.$nama_file;
UploadImage($nama_file_unik); // this is my custom function
$sql="INSERT INTO produk(gambar)VALUES (?)";
$query=$this->db->query($sql,array($nama_file_unik));
if($query)
{
echo "BERHASIL";
}
else
{
echo "GAGAL";
}
}
UPDATE NEW
I finally able to use $_FILES, I need to load the library inside the controller Constructor.
now the new problem is there is no file uploaded even using do_upload() function inside my own custom made function
this is my custom made function
function UploadImage($fupload_name){
// SET DATA FILE NYA
$config['file_name'] = $fupload_name;
$config['upload_path'] = 'http://localhost/mobileapp/assets/gambar/';
var_dump($config['upload_path']);
//load the upload library
$CI =& get_instance();
$CI->load->library('upload',$config);
//Upload the file
if( !($CI->upload->do_upload('fupload'))){
$error = $CI->upload->display_errors();
}else{
$file_data = $CI->upload->data();
}
}
now as you can see above, I'm trying to change the file_name to a new randomly-generated name (done in the model) using $config['file_name'] = $fupload_name; and making a new object because obviously I need to do this to load library and use the do_upload() method.
but I still cannot use it. now I'm stuck again
Pass $_FILES array from controller to model function, add new file name in config array and use do_upload() directly like,
Controller Function:
public function input_file(){
$this->load->model('input_model');
$this->input_model->put_file($_FILES); // pass $_FILES Array
}
Model Function:
public function put_file($files){
$config['allowed_types'] = '*';
$acak = rand(1,99);
$config['file_name'] = $acak.$files['fupload']['name'];
$this->load->library('upload',$config);
$data = array(
'location_file' => $files['fupload']['tmp_name'],
'type_file' => $files['fupload']['type'],
'name_file' => $files['fupload']['name']
);
if (!$this->upload->do_upload('fupload')) { // pass field name here
$this->upload->display_errors('<p>', '</p>');
} else {
$sql="INSERT INTO produk(gambar)VALUES (?)";
$query=$this->db->query($sql,array($nama_file_unik));
if($query) {
echo "BERHASIL";
} else {
echo "GAGAL";
}
}
}
upload_path in configs must be absolute or relative path and not an url.
So you can something like this():
$config['upload_path'] = './uploads/';
OR this:
$config['upload_path'] = FCPATH . 'uploads/';
Note: FCPATH is absolute path of your index.php folder.
I am trying to get my app to be able to handle uploads. This is the add action in DealsController.php.
<?php
public function add() {
if ($this->request->is('post')) {
$this->request->data['Deal']['user_id'] = $this->Auth->user('id');
$this->Deal->create();
if ($this->Deal->uploadFile($this->request->data['Deal']['pic'])){
$file = $this->request->data['Deal']['pic'];
$this->request->data['Deal']['pic'] = $this->request->data['Deal']['pic']['name'];
if ($this->Deal->save($this->request->data)) {
$this->Session->setFlash(__('Your deal has been saved. %s', h(serialize($file)) ));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Unable to add your deal. %s', h(serialize($file)) ));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Unable to upload the file. Please try again. %s', h(serialize($this->request->data['Deal']['pic']))));
}
}
The uploadFile function is defined in the model in Deal.php
<?php
public function uploadFile( $check ) {
$uploadData = array_shift($check);
if ( $uploadData['size'] == 0 || $uploadData['error'] !== 0) {
return false;
}
$uploadFolder = 'files'. DS .'your_directory';
$fileName = time() . '.pdf';
$uploadPath = $uploadFolder . DS . $fileName;
if( !file_exists($uploadFolder) ){
mkdir($uploadFolder);
}
if (move_uploaded_file($uploadData['tmp_name'], $uploadPath)) {
$this->set('pic', $fileName);
return true;
}
return false;
}
`uploadFile` keeps returning false and I get my
Unable to upload the file. Please try again.
a:5:{s:4:"name";s:7:"012.PDF";s:4:"type";s:15:"application/pdf";s:8:"tmp_name";s:14:"/tmp/phpw0uVGS";s:5:"error";i:0;s:4:"size";i:70118;}
flash. Which is confusing, since it makes it look like the file was actually uploaded to a temp dir. I tried different paths for move_uploaded_file but nothing worked. Does this have something to do with file permissions? It couldn't be file-size, since my upload file was only about 80 KB.
Solution: Don't try to code it yourself. Use one of the already existing file upload plugins for CakePHP, which will handle all the ins and outs behind the scenes, with minimal coding on your part.
I personally use https://github.com/josegonzalez/upload
Okay so I've been messing with this for a couple hours now, reading the docs and browsing forums but I cannot find out why this upload form isn't working.
The entire form works perfectly, data saves to the DB and everything. But I just added an image upload input and it doesn't work! I have followed the exact tutorial in the docs, as well as several others.
Here is the code that processes the form submit ($this->page_m is my model):
public function edit ($id = NULL)
{
// Fetch a page or set a new one
if ($id) {
$this->data['page'] = $this->page_m->get($id);
count($this->data['page']) || $this->data['errors'][] = 'page could not be found';
}
else {
$this->data['page'] = $this->page_m->get_new();
}
// Pages for dropdown
$this->data['pages_no_parents'] = $this->page_m->get_no_parents();
// Process the form
if ($this->form_validation->run('page_rules') == TRUE) {
$data = $this->page_m->array_from_post(array(
'title',
'slug',
'body',
'template',
'parent_id'
));
if(!empty($_FILES['userfile'])) {
$this->do_upload();
}
$this->page_m->save($data, $id);
redirect('admin/page');
}
// Load the view
$this->data['subview'] = 'admin/page/edit';
$this->load->view('admin/_layout_main', $this->data);
}
and here is the code that processes the photo upload, which is called right after the $this->form_validation->run() check:
//upload a slider photo
public function do_upload() {
$config = array(
'allowed_types' => 'jpg|jpeg|gif|png',
'upload_path' => site_url('uploads/')
);
$this->load->library('upload');
$this->upload->initialize($config);
$field_name = "userfile";
if ( ! $this->upload->do_upload($field_name)) {
$this->data['error'] = array('error' => $this->upload->display_errors());
$this->data['subview'] = 'admin/page/edit';
$this->load->view('admin/_layout_main', $this->data);
} else {
return true;
}
}
I have purposely made this upload script as simple and basic as possible for debugging purposes, but still I have had no success in getting this form to upload properly.
After I get the upload working I need to save the image name in my database table, but that is besides the point right now. I just need to get this actually uploading.
SOLVED -- INVALID UPLOAD DIRECTORY
To debug your script you should try and echo out the value returned by $this->upload->display_errors();
Try changing your do_upload() methods last if{} else {} statement to the following:
if ( ! $this->upload->do_upload($field_name)) {
// return the error message and kill the script
echo $this->upload->display_errors(); die();
$this->data['error'] = array('error' => $this->upload->display_errors());
$this->data['subview'] = 'admin/page/edit';
$this->load->view('admin/_layout_main', $this->data);
} else {
return true;
}
Hopefully this will help you find out what is causing the problem.
same problem with mine, I resolve that by upgrading CodeIgniter,
my old version is 3.1.2, then i just upgrade to CI-3.1.3,
just replace the system folder in root folder,
after that, the problem resolve in live server,
i hope my suggest is useful to use
It's come to my attention that my image processing code that I currently have in my controller would be better suited in a model, but I'm not sure even where to start to do this.
I have a controller that handles uploading an image, renaming the file and storing it in the database using Doctrine:
<?php
class Addimage extends Controller
{
function index()
{
$vars['content_view'] = 'uploadimage';
$this->load->view('template', $vars);
}
public function do_upload()
{
$this->load->library('form_validation');
if($this->_submit_validate() == FALSE)
{
/*THIS CODE BLOCK IS DUPLICATED FROM MY HOME PAGE CONTROLLER - this is one of the reasons I want to refactor.*/
$vars['recentimages'] = Doctrine_Query::create()
->select('photo_path')
->from('Gif g')
->orderBy('g.created_at DESC')
->limit(12)
->execute();
$vars['title'] = 'Home';
$vars['content_view'] = 'welcome_message';
$this->load->view('template_front', $vars);
}
else
{
$basedir = $this->config->item('server_root') . $this->config->item('upload_dir');
//If the directory doesn't already exist, create it.
if (!is_dir($basedir))
{
mkdir($basedir, 0777);
}
$config = array(
'allowed_types' => "gif",
'upload_path' => $basedir,
'remove_spaces' => true
);
$this->load->library('upload', $config);
if(!$this->upload->do_upload())
{
$data['error'] = 'There was a problem with the upload';
}
else
{
$image_data = $this->upload->data();
$fileName = $image_data['file_name'];
$title = $this->input->post('title');
//Rename File based on how many of that letter
//are already in the database
$imageCount = Doctrine_Query::create()
->select('COUNT(i.id) as num_images')
->from('Gif i')
->execute();
$imageCount = $imageCount[0]->num_images++;
//Rename file based on title and number of images in db.
$newFileName = preg_replace('/[^a-zA-Z0-9\s]/', '', $title) . '_' . $imageCount . $image_data['file_ext'];
rename($basedir . $fileName, $basedir . $newFileName);
$gif = new Gif();
$gif->photo_path = $newFileName;
$gif->title = $title;
if(Current_User::user())
{
$gif->User = Current_User::user();
}
else
{
$gif->User = Doctrine::getTable('User')->findOneById($this->config->item('anonuid'));
}
$gif->save();
}
redirect('/', 'location');
}
}
private function _submit_validate()
{
$this->form_validation->set_rules('title', 'Title', 'required');
return $this->form_validation->run();
}
}
I would like to be able to have most of this in a model, because I'm using a template system for the views where my uploadimage.php view is just the upload form so that it can be dropped on any page. Also, I only have experience using Doctrine models.
Thanks for any help in advance
I had a very similar issue on my own project: duplication in the controllers. I think in your case it makes sense to only move parts of that logic into the model, because most of it actually makes sense to be in a controller.
Rendering view definitely should be in a controller, and input validation as well. I would move the transactional part to the model: the SQL, file handling and image manipulation.
You will then still have some duplication but I see no other way since controller logic and model logic are so interwoven in this case.