I am new to magento and i am Creating Custom module for File upload in magento admin.
Right now i have post the upload file in my module controller.
Here i have used move_uploaded_file to upload file in same directory with in controller folder.
below code i have used for file upload in controller
$file_name=$_FILES["file"]["name"];
$file_path="import/$file_name";
if(move_uploaded_file($_FILES["file"]["tmp_name"],$file_path))
{
// my files not uploading
}
I can't able to upload the file in directory folder.
So what i am doing wrong? or suggest me if using move_uploaded_file in magento controller is correct way to handle file upload ?
Thanks.
In order to upload file in Magento, you can use Varien_File_Uploader::save() method as:
if(isset($_FILES['file']['name']) && $_FILES['file']['name'] != '') {
try {
$fileName = $_FILES['file']['name'];
$fileExt = strtolower(substr(strrchr($fileName, "."), 1));
$fileNamewoe = rtrim($fileName, $fileExt);
$fileName = str_replace(' ', '', $fileNamewoe) . '.' . $fileExt;
$uploader = new Varien_File_Uploader('file');
$uploader->setAllowedExtensions(array('png', 'jpg')); //allowed extensions
$uploader->setAllowRenameFiles(false);
$uploader->setFilesDispersion(false);
$path = Mage::getBaseDir('media') . DS . 'yourModuleFolder';
if(!is_dir($path)){
mkdir($path, 0777, true);
}
$uploader->save($path . DS, $fileName );
} catch (Exception $e) {
echo $e->getMessage();
}
}
Related
I'm uploading an image to S3 with Laravel as follows:
$image = $request->image;
if (!empty($image)) {
$imageFileName = $user_id.'_'.rand(11111111, 99999999) . '.' . $image->getClientOriginalExtension(); // Rename Image
try
{
//Send to S3
$s3 = Storage::disk('s3');
$filePath = '/profile/' . $imageFileName;
$s3->put($filePath, file_get_contents($image), 'public');
$image = Storage::cloud()->url($imageFileName);
}
catch(\Exception $exx)
{
//Send to Logs Etc
}
The image uploads successfully but I need to store the URL in my database. This is being called here:
$image = Storage::cloud()->url($imageFileName);
The issue is the URL being returned, it looks like this:
http://test-env.XXX.us-west-2.elasticbeanstalk.com/profile/https://elasticbeanstalk-us-west-2-123XXX456XXX.s3.us-west-2.amazonaws.com/6_52644340.jpg
Hence:
http://mentr-test-env.2w8sh3esch.us-west-2.elasticbeanstalk.com/profile/
is somewhat-correct. But the next piece is missing the 'profile' sub-folder, and obviously starts at HTTPS again:
https://elasticbeanstalk-us-west-2-123XXX456XXX.s3.us-west-2.amazonaws.com/6_52644340.jpg
It would appear I'm getting two halves of the link in a single string. I don't edit the $image variable anywhere else.
The correct link is:
https://elasticbeanstalk-us-west-2-123XXX456XXX.s3.us-west-2.amazonaws.com/profile/6_52644340.jpg
I have confirmed the files are uploading correctly and publicly available.
I have tried calling:
$image = Storage::cloud()->url($filePath);
And this returns:
http://test-env.XXXX.us-west-2.elasticbeanstalk.com/profile/https://elasticbeanstalk-us-west-2-XXX123XXX.s3.us-west-2.amazonaws.com//profile/6_31595766.jpg
Update
I just noticed the first part of the returned URL is the BeanStalk instance URL with the /profile/ added. This is even stranger as I don't wish to use Beanstalk, I only want to use S3.
If you want to store the entire url you can get it from the return variable passed back from the put() function.
$s3_url = $s3->put($filePath, file_get_contents($image), 'public');
Sometimes I like to just store the path though and save just that piece to the database then I can pass the path to Storage::url($filePath); and it still works.
$image = $request->image;
if (!empty($image)) {
$imageFileName = $user_id.'_'.rand(11111111, 99999999) . '.' . $image->getClientOriginalExtension(); // Rename Image
try
{
//Send to S3
$s3 = Storage::disk('s3');
$filePath = '/profile/' . $imageFileName;
$s3->put($filePath, file_get_contents($image), 'public');
$image = Storage::cloud()->url('s3-url/s3-bucket'.'/'.$filepath);
}
catch(\Exception $exx)
{
//Send to Logs Etc
}
I am using aws to store my images and the code in the controller looks like this:
Storage::disk('3')->put($file->getClientOriginalName(), fopen($file, 'r+'), 'public');
The images are being saved in my local storage.
Now though, I want to be able to create a subfolder to keep the images organized.
For my case, it is registering a business. Therefore I want the images to be stored in a subfolder containing the appropriate business id. I tried this:
Storage::disk('3')->put($file->getClientOriginalName(), fopen($file, 'r+'), 'public/' . $business->id.
More about the controller is as follows:
$input = $request->all();
$files = isset($input['file']) ? $input['file'] : array ();
$business_names = json_decode($input['business_names'], true);
$business_details = json_decode($input['business_details']);
$share_amount = json_decode($input['share_amount'], true);
$entity = json_decode($input['entity'], true);
$directors = json_decode($input['directors'], true);
$shareholders = json_decode($input['shareholders'], true);
$appointments = json_decode($input['appointments'], true);
$input['user_id'] = Auth::user()->id;
Log::info(Auth::user());
Log::info($request->user());
/* Create Business Record */
$business = new Business;
$business->business_names = json_encode($business_names);
$business->share_amount = $share_amount ?: 0;
$business->entity = $entity ?: '';
$business->business_physical_address = json_encode($business_details->physical_address);
$business->has_business_postal_address = $business_details->has_postal_address;
$business->business_postal_address = json_encode($business_details->postal_address);
$business->user_id = $input['user_id'];
$business->save();
/* Create a new folder in storage/app/files named after the business ID */
Storage::makeDirectory('files/' . $business->id);
/* Upload Files */
// TODO: file storing?
foreach($files as $file) {
if ($file) {
Storage::disk('3')->put($file->getClientOriginalName(), fopen($file, 'r+'), 'public/' . $business->id);
// $file->storeAs('files/' . $business->id, $file->getClientOriginalName());
}
}
When I try to save a business now, I see the following error:
C:\xampp\htdocs\startingabandbaby\vendor\league\flysystem\src\Adapter\Local.php(356):
Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(8,
'Undefined index...', 'C:\xampp\htdocs...', 356, Array)
Since I was able to store images before, I am assuming that it is something to do with concatenating the business id.
How can I create a subfolder with the business id everytime I create a new business and add all the files in that same folder?
As per our discussion, you can use below 2 solutions:
1) put():
$path = Storage::disk('s3')->put(
'/files/'. $business->id, //path you want to upload image to S3
file_get_contents($request->file('file')), //fileContent
'public' //visibility
2) putFileAs(): To achieve the same thing withputFileAs(), I needed to write it as below. 1st parameter expects the directory name, I left it blank as I'm mimicking the directory name in s3 through the filename.
$path = Storage::disk('s3')->putFileAs(
'', // 1st parameter expects directory name, I left it blank as I'm mimicking the directory name through the filename
'/files/'. $business->id,
$request->file('file'), //3rd parameter file resource
['visibility' => 'public'] //options
);
Hope this will helps you!
After some research I ended up with the following:
$directory = 'public/' . $business->id;
Storage::disk()->makeDirectory($directory);
foreach($files as $file) {
if ($file) {
Storage::disk()->put($directory . '/' .$file->getClientOriginalName(), fopen($file, 'r+'));
}
}
I have code written to allow someone to enter a date. if the submit date equals the file name then codeigniter should download the file to the desktop. The code shown makes sense to me but when I run it I get 'file was not found'. I can pull the file up on the server though and the name matches what is returned in the mysql database. My end goal is to be able to download the file with the same filename as my submission_date field
if($this->input->post('submit')) {
$trlr_num = $this->input->post('trlr_num');
} elseif($this->uri->segment(4)) {
$trlr_num = $this->uri->segment(4);
}
if( !empty($trlr_num)) {
$query = $this->trailer_model->select_trailer_draw($trlr_num);
$result =& $query->row_array();
if( !empty($result)) {
// Get filepath to bill
$directory = 'http://intranet.gmwdc.com/inc/img/inspection/upload';
$file = $directory.'/'.$result['submission_date'];
$this->load->helper('download');
if(file_exists($file)) {
$data = file_get_contents($file);
force_download($result['submission_date'],$data);
} else {
$this->session->set_status_data('error','File was not found.');
}
return;
} else {
$this->session->set_userdata('error','No Inspection Draw Found');
}
}
You might be referring wrong directory or file name. Also, it seems that $file is having no extension.
$file = $directory . '/' . $result['submission_date'] . $extension;
Edited
Instead of $directory try Codeigniter FCPATH which points to your Codeigniter installation directory.
$file = FCPATH . 'dir1/dir2/' . $result['submission_date'];
I am now troubling with this small error. I have a module which is using to upload images. Now this is my code for saving the file. It is defined in saveAction() method of controller.
<?php
/*rest part*/
$postData = $this->getRequest()->getPost();
if(isset($_FILES['banner_img_1']['name']) and (file_exists($_FILES['banner_img_1']['tmp_name'])))
{
try
{
$uploader = new Varien_File_Uploader('banner_img_1'); $uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
$uploader->setAllowRenameFiles(false);
$uploader->setFilesDispersion(false);
$path = Mage::getBaseDir('media') . DS . 'banner' . DS ;
$uploader->save($path, $_FILES['banner_img_1']['name']);
$postData['banner_img_1'] = $_FILES['banner_img_1']['name'];
}
catch(Exception $e)
{
}
}
else
{
if(isset($postData['banner_img_1']['delete']) &&
$postData['banner_img_1']['delete'] == 1)
$postData['image_main'] = '';
else
unset($postData['banner_img_1']);
}
However this is not storing my image in media/banner folder. When I use path as
<?php
$path = Mage::getBaseDir('media') . DS ;
it saves image in media folder. I dont know the reason why it happens like this. when I print the $path variable, it currectly points towards media/banner folder. What is the error in my code? Please help me to solve this minor error. Thanks in advance..
Try this code in the try block {}
$path = Mage::getBaseDir('media') . DS . 'banner' . DS .'banner'.DS;
$uploader = new Varien_File_Uploader('banner_img_1');
$uploader->setAllowedExtensions(array('jpg','png','gif'));
$uploader->setAllowRenameFiles(false);
$uploader->setFilesDispersion(false);
$destFile = $path.$_FILES['banner_img_1']['name'];
$filename = $uploader->getNewFileName($destFile);
$uploader->save($path, $filename);
$post_data['banner_img_1']='banner/banner/'.$filename;
I am making an application in which i am uploading file from my custom tab as follows
i created a observer for event called catalog_product_save_after. In the particular function, i am uploading those files to catalog/product folder and its get uploaded to those folder without any error.
But when i am trying to assign those images to that particular product, i got the following error.
File was not uploaded at file E:\xampp\htdocs\magento\lib\Varien\File\Uploader.php on line 152
If i check system.log then i see the 2012-08-24T11:33:15+00:00 ERR (3): User Error: Some transactions have not been committed or rolled back in E:\xampp\htdocs\magento\lib\Varien\Db\Adapter\Pdo\Mysql.php on line 3645 this error.
My observer function is as follows
public function Savedata($observer)
{
$params = Mage::app()->getRequest()->getParams();
$product = $observer->getEvent()->getProduct();
$product_id = $product->getId();
$filesData = array();
$keysData = array_keys($_FILES);
foreach($keysData as $keys)
{
$uploader = new Varien_File_Uploader("$keys");
$uploader->setAllowedExtensions(array('jpeg', 'jpg', 'png', 'tiff'));
$uploader->setAllowRenameFiles(true);
$uploader->setFilesDispersion(false);
$path = Mage::getBaseDir('media') . DS . "catalog" . DS . "product";
if(!is_dir($path))
{
mkdir($path);
}
$extension = pathinfo($_FILES["$keys"]['name'], PATHINFO_EXTENSION);
$date = new DateTime();
$file_name = $keys . "_" . $product_id . "." . $extension;
$_FILES["$keys"]['name'] = $file_name;
$uploader->save($path, $_FILES["$keys"]['name']);
$filesData[] = $path .DS. $_FILES["$keys"]['name'];
}
print_r($filesData);
///till this works file.. when i add following code, program dies.
try
{
$productData = Mage::getModel('catalog/product')->load($product_id);
print_r($productData->getData());
foreach($filesData as $file)
{
$productData->addImageToMediaGallery($file, "image" ,false, false);
}
$productData->save();
$productData = Mage::getModel('catalog/product')->load($product_id);
print_r($productData->getData());
}
catch (Exception $e)
{
echo $e->getMessage() . "||" . $e->getCode() . "||" . $e->getFile() . "||" . $e->getLine();
}
exit();
}
any suggestion where i am going wrong? why this error occur?
i am using magento 1.7
I see that you're going to update your catalog/product object when you're saving it.
You are using event catalog_product_save_after.
Inside the observer, you call:
$productData = Mage::getModel('catalog/product')->load($product_id);
...
$productData->save();
$productData is catalog/product object -> you saved it.
You can guess what will happen, it will trigger event catalog_product_save_after and so on, looping forever.
I see that you call $productData->save(); because in this event, the value has been saved and can not be changed.
So instead of using catalog_product_save_after, you can use catalog_product_save_before.
The same like your code, but remove $productData->save(); because it will automatically call save.
Mage_Core_Model_Abstract
public function save()
{
/**
* Direct deleted items to delete method
*/
if ($this->isDeleted()) {
return $this->delete();
}
if (!$this->_hasModelChanged()) {
return $this;
}
$this->_getResource()->beginTransaction();
$dataCommited = false;
try {
$this->_beforeSave();
if ($this->_dataSaveAllowed) {
//see this line below, it will call save, so you don't need to call save in your `catalog_product_save_before` (no looping forever)
$this->_getResource()->save($this);
$this->_afterSave();
}
$this->_getResource()->addCommitCallback(array($this, 'afterCommitCallback'))
->commit();
$this->_hasDataChanges = false;
$dataCommited = true;
} catch (Exception $e) {
$this->_getResource()->rollBack();
$this->_hasDataChanges = true;
throw $e;
}
if ($dataCommited) {
$this->_afterSaveCommit();
}
return $this;
}