setting $this->data in a method then gets unset - php

I am uploading an image with codeigniter, and in the method I am doing the following,
if(isset($_FILES['product_image']['name'])) {
//some setup needed
$config['upload_path'] = "./media/images/products";
$config['allowed_types'] = "png|gif|jpg|jpeg";
$config['max_width'] = 1490;
$config['max_height'] = 400;
//make sure the library is running with clean config
$this->upload->initialize($config);
//do the upload
if(!$this->upload->do_upload('product_image')){
$this->data['image_error'] = $this->upload->display_errors();
$this->template->build('/admin/products/create', $this->data);
} else {
$this->data['image_data'] = $this->upload->data();
//die(print_r($this->data));
$this->template->build('/admin/products/create', $this->data);
}
}
so basically I check to see if there is something in the $_FILES and then upload if there is assigning $this-data['image_data'] with the upload data along the way. However when I come to process the data i.e. save the filename in a database, I cannot access $this->data['image_data'] below is how I am trying to use it,
if($this->input->post("submit_create") == "Save") {
die(print_r($this->data['image_data']));
}
however I get the following error,
Message: Undefined index: image_data
why is this I though assigning things to $this made them accessible not just throughout the method but the entire controller?

I think, when you are printing image_data at this point in your example:
if($this->input->post("submit_create") == "Save") {
die(print_r($this->data['image_data']));
}
You should actually be using $image_data instead:
if($this->input->post("submit_create") == "Save") {
die(print_r($image_data));
}

Related

Use do_upload function with hardcoded image location (Codeigniter)

My problem is following. I'm writing this test data seed file. I already have all functionalities wrote (creating thumbnalins, hd, watermarking img, etc...) so now I would like just to reuse this code, but with some hardcoded image data location.
$imgToUploadLocation = "../../static/img/test.jpg";
$_FILE['userfile'] = imgToUploadLocation;
$config['upload_path'] = '/pictures/';
$config['allowed_types'] = 'jpeg|jpg';
$config['remove_spaces'] = true;
$config['max_size'] = '25000';
$config['encrypt_name'] = true;
$this->upload->initialize($config);
if ($this->upload->do_upload()) {
echo "finaly!";
} else {
echo "error";
}
The problem is that however i specify my image location i will always get error you did not select any image to upload.
I wonder how to use upload library without view form? If you need any additional informations please let me know and I will provide. Thank you!
This is not the proper way of defining. Files are expected in a certain way on the $FILES global variable to be uploaded.
In order to define the file you want to upload do:
$_FILES['userfile']['name'] = 'what name you want';
$_FILES['userfile']['tmp_name'] = $imgToUploadLocation;
Read more about the $_FILES in https://secure.php.net/manual/en/features.file-upload.post-method.php

Unable to upload a base64 encoded image using Codeigniter

I have to upload a base64 encoded image that i am receiving from android application. I am using php codeigniter framework.
While searching through the forum, the question at this link How to upload base64encoded image in codeigniter is same as mine, but the solution there is not working for me.
Here is the code that i have written:
private function _save_image() {
$image = base64_decode($_POST['imageString']);
#setting the configuration values for saving the image
$config['upload_path'] = FCPATH . 'path_to_image_folder';
$config['file_name'] = 'my_image'.$_POST['imageType'];
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$config['max_size'] = '2048';
$config['remove_spaces'] = TRUE;
$config['encrypt_name'] = TRUE;
$this->load->library('upload', $config);
if($this->upload->do_upload($image)) {
$arr_image_info = $this->upload->data();
return ($arr_image_info['full_path']);
}
else {
echo $this->upload->display_errors();
die();
}
}
I am getting "you did not select a file to upload"
Thanks for your time.
The error is occurring because codeigniter's upload library will look into the $_FILES superglobal to and search for a index you give it at the do_upload() call.
Furthermore (at least in version 2.1.2) even if you would set up the $_FILES superglobal to mimic the behaviour of a file upload it wouldn't pass because the upload library uses is_uploaded_file to detect exacly that kind of tampering with superglobals. You can trace the code in system/libraries/Upload.php:134
I'm afraid that you will have to re-implement size checking and file renaming and moving (I would do this) or you can modify codeigniter to omit that check, but it could make upgrading the framework later difficult.
Save the $image variable's content to a temporary file, and set up the $_FILES to look like this:
$temp_file_path = tempnam(sys_get_temp_dir(), 'androidtempimage'); // might not work on some systems, specify your temp path if system temp dir is not writeable
file_put_contents($temp_file_path, base64_decode($_POST['imageString']));
$image_info = getimagesize($temp_file_path);
$_FILES['userfile'] = array(
'name' => uniqid().'.'.preg_replace('!\w+/!', '', $image_info['mime']),
'tmp_name' => $temp_file_path,
'size' => filesize($temp_file_path),
'error' => UPLOAD_ERR_OK,
'type' => $image_info['mime'],
);
Modify the upload library. You can use codeigniter's built in way of Extending Native Libraries, and define a My_Upload (or your prefix) class, copy-paste the do_upload function and change the following lines:
public function do_upload($field = 'userfile')
to:
public function do_upload($field = 'userfile', $fake_upload = false)
and the:
if ( ! is_uploaded_file($_FILES[$field]['tmp_name']) )
to:
if ( ! is_uploaded_file($_FILES[$field]['tmp_name']) && !$fake_upload )
and in your controller, call do_upload() with the flowing parameters:
$this->upload->do_upload('userfile', true);
You are aware, that if you are receiving an Base64 encoded image, as a string, then you do not need to use the Upload class.
Instead, you just need to decode it using base64_decode and then use fwrite/file_put_contents to save the decoded data...
$img = imagecreatefromstring(base64_decode($string));
if($img != false)
{
imagejpeg($img, '/path/to/new/image.jpg');
}
Credit: http://board.phpbuilder.com/showthread.php?10359450-RESOLVED-Saving-Base64-image.

codeigniter photo upload no error warning on non allowed types files

Here is upload function:
$config['upload_path'] = './photos/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 1024 * 2;
$config['encrypt_name'] = true;
$this->load->library('upload', $config);
//$this->upload->initialize($config);
if (!$this->upload->do_upload("photo_data"))
{
$this->error = true;
$this->response = $this->upload->display_errors('', '');
}
else
{
$this->upload->data();
$this->response = "Photo successfully changed.";
}
$array = array(
'error' => $this->error,
'response' => $this->response
);
return $array;
However in order to test that it doesnt allow file types except the one that i allow i renamed a video to .jpg and tried to upload it...
It didnt proceed but it didnt also send an error message... i suppose somwhere in the upload class returns false... any idea how to make sure it sends a message to the user first?
How are you printing the errors in your view? The method returning false somewhere in the upload class is the one you already checked for FALSE, i.e. $this->upload->do_upload()
You should pass those errors to a view, if you want the site to display them:
This assumes the code you posted is from a controller:
$array = array(
'error' => $this->error,
'response' => $this->response
);
$this->load->view('upload_view',$array);
//instead of returning, as "return" in a controller makes little sense. If you're inside a model, then, get the returned value in a controller and pass it to a view.
In your "upload_view.php" view file:
<div class="<?php $error? 'error' : 'success';?>"><?php echo $response;?></div>

How to validate uploads as a group in CodeIgniter, so they all either upload or fail

Firstly, I'm not asking how to perform a multi-file upload using CodeIgniter, but rather how to prevent any/all files from being uploaded if the last one in line fails (due to filetype, size, etc.). Basically I'm looking to use CI's file validation up front (before anything is uploaded), and if everything looks good, perform all uploads.
I have a form that uploads two files. If the first file passes validation and the do_upload() method returns TRUE, but the second file fails, the first file was still uploaded -- how can I prevent this?
Here's my code:
// Controller
function upload_files()
{
// Configure first file upload
$config['upload_path'] = 'public/mp3/';
$config['overwrite'] = FALSE;
$config['allowed_types'] = 'mp3';
$config['max_size'] = '20000';
$config['remove_spaces'] = TRUE;
$this->upload->initialize($config);
// Perform first file upload
if ($this->upload->do_upload('mp3'))
{
// Store upload file info for later use
$mp3_info = $this->upload->data();
// Configure second file upload
$config['upload_path'] = 'public/doc/';
$config['overwrite'] = FALSE;
$config['allowed_types'] = 'doc|docx';
$config['max_size'] = '3000';
$config['remove_spaces'] = TRUE;
$this->upload->initialize($config);
// Perform second file upload
// Even if this fails, the first file was still uploaded
if ($this->upload->do_upload('doc'))
{
// Store upload file info for later use
$doc_info = $this->upload->data();
// Perform database interactions here
}
else
{
echo $this->upload->display_errors();
}
}
else
{
echo $this->upload->display_errors();
}
}
No dice! You can't validate an upload from php or codeigniter unless you execute the upload. How can php validate something it doesn't yet have access to?
You have to do some validation up-front with javascript. If all files pass the js validation, then upload the files and complete validation with php/codeigniter.

codeigniter: loading variables and view from within model

I'm building an image uploading script (for the first time) in Codeigniter and the way I have it is that if the image upload form gets validated it performs the following code in a model:
public function upload($id) //function to handle the initial image upload before crop
{
$config['image_library'] = 'gd2';
$config['source_image'] = '/path/to/image/mypic.jpg';
$config['create_thumb'] = TRUE;
$config['maintain_ratio'] = TRUE;
$config['width'] = 75;
$config['height'] = 50;
$this->load->library('image_lib', $config);
$this->image_lib->resize();
$config['upload_path'] = 'images/uploads/temp/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = '2048';
$config['max_width'] = '1024';
$config['max_height'] = '768';
$this->load->library('upload', $config);
$file_data = $this->upload->data();
if ( ! $this->upload->do_upload() )//the default parameter of do_upload() is 'userfile' (meaning the name of the form input)
{
$error = '<p>Upload failed!</p> <p>Please make sure the image is in a .jpg, .gif or .png format and that it\'s no larger than 1028 x 768 pixels in dimension. Also it can\'t be more than 2MBs in size. If this problem persists, please contact webmaster#dreamsy.org.</p>';
$this->session->set_flashdata('error', $error);
redirect(base_url().'community/upload_image');
}
else
{
$image_path = base_url().'images/uploads/temp/'.$file_name;
//$data = array( 'upload_data' => $this->upload->data() );
//$this->load->view('community/upload_success');
$this->load->helper('form', 'url');
$vars['id'] = $this->uri->segment(3);
$vars['$image_path'] = $image_path;
$vars['$file_data'] = $file_data;
$this->load->vars($vars);
$this->template->write_view('content', 'community/upload_success');
$this->template->render();
}
}>template->render(); //template library
But when I call the variables that are loaded (via load->vars()) they don't get loaded and when the page loads I get "undefined variable" errors. I suspect it's not possible to pass variables from a model to the view even when the view is loaded from within the model as I have done above. Or maybe I'm just doing something incorrectly (as I'm a bit of a n00b).
Would you even take this route? Would it make more sense to pass the variables to the controller and then to load the view from the controller? Or something else I haven't considered at all? lol
Any help is greatly appreciated. Thanks in advance.
*edit:
I also have the $image_path variable inside of an
Would you even take this route? Would it make more sense to pass the variables to the controller and then to load the view from the controller? Or something else I haven't considered at all?
Yeah, generally speaking it is somewhat accepted to have your views talk directly to the model and vice versa but only when using a presentation layer. In the case of CI, I think it's best to have all the data loaded in from your controller to your view when you render the view like this:
$this->load->view('your-view', $data);
To pass the vars from the model to the controller you can call methods on your model like this:
// Your_Model is the class name of your model
// your_model is the variable name it gets injected into
$this->load->model('Your_Model','your_model');
$data['some_data'] = $this->your_model->get_some_data();
To define those getters in your model, you define a function like this:
function get_some_data()
{
return $this->some_data;
}
That way you create an API into your data, and you can have the getter retrieve whatever you will need in the format you will need it in.
Assuming the line:
$this->load->vars($vars);
is where you want to load your view, then it should be:
$this->load->view('nameofview', $vars);

Categories