I'm not getting the information I am looking for from research. I'd like to perform a rename on the file upload after it has uploaded. I need the original filename as well as renaming it. Here is what I have so far:
$form = new Sam_Form_Database($this->resource);
$form->setMethod(Zend_Form::METHOD_POST);
if($this->getRequest()->isPost()){
if($form->isValid($this->getRequest()->getPost())){
$data = $form->getValues();
try {
$form->fileelement->receive();
$originalFilename = pathinfo($form->fileelement->getFileName());
$newFilename = Sam_Util::generateHash().'.'.$originalFilename['extension'];
$filterFileRename = new Zend_Filter_File_Rename(array(
'target' => $newFilename,
'overwrite' => true,
'keepExtension' => true
));
$filterFileRename->filter($form->fileelement->getFileName());
} catch(Exception $e){
Sam::exception("Cannot upload file");
}
Sam_Util::insertDataIntoDatabase($data,$this->resource);
Sam_Util::redirectSimple('list');
}
The problems:
nothing seems to be uploading
before when it was uploading it wasn't renaming the file in the destination
What I need is a fluent way to handle uploading, retrieving the original filename, and performing a rename on the target file using zend.
Related
first of all to explain what I mean by my question, when I upload my files to the local storage I save them the following way:
$files = $request->file('files');
if ($request->hasFile('files')) {
foreach ($files as $file) {
//Get filename with the extension
$fileNameWithExt = $file->getClientOriginalName();
//Filename to store example: lead_4_document.pdf
$fileNameToStore = 'lead_' . $lead->id . '_' . $fileNameWithExt;
//Upload image
$path = $file->storeAs('/user_uploads', $fileNameToStore);
$lead->uploadFile()->create(array('filename' => $fileNameToStore, 'file_url' => $path, 'lead_id' => $lead->id));
}
}
So essentially I prepend lead_ the lead id and another _ to whatever the file is originally called during upload. The problem I face now is that I need to retrieve the associated files according to my lead ids. Here is my attempt so far:
$searchParam = 'lead_'.$lead->id.'_';
//$fileNames = File::glob('storage/user_uploads/'.$searchParam.'*');
//$files = File::get($fileNames);
$allFiles = Storage::files('user_uploads');
dd($allFiles);
Just to clarify, the 'File::glob' way seems to work, though it only outputs the names of the files not the actual files as object, which is what I need.
Okay, so I took a step back and went about this whole associated uploaded file to lead relationship a different way. Here is how I did it, just in case anyone stumbles across this and find themselves in the same boat as me.
The file upload now does a couple of things:
//check if file(s) is present in the request
if ($request->hasFile('files')) {
//checks if a directory already exists for a given lead (by id)
if (Storage::exists('/leads/'.$request->lead_id)) {
//if yes set the directory path to the existing folder
$directory = '/leads/'.$request->lead_id;
}
else {
//if not create a new directory with the lead id
Storage::makeDirectory('/leads/'.$request->lead_id);
$directory = '/leads/'.$request->lead_id;
}
foreach ($files as $file) {
//Get filename with the extension
$fileNameWithExt = $file->getClientOriginalName();
//Filename to store example: lead_4_document.pdf
$fileNameToStore = 'lead_' . $lead->id . '_' . $fileNameWithExt;
//Upload image
//'/user_uploads'
$file->storeAs($directory, $fileNameToStore);
//$lead->uploadFile()->create(array('filename' => $fileNameToStore, 'file_url' => $path, 'lead_id' => $lead->id));
}
}
So essentially, instead of trying to put all files into a single folder then checking the individual files for the 'lead_##' prepend, I instead create a folder with the id of the lead, this I then use the following way in my view function:
$directory = '/leads/'.$lead->id;
if (Storage::exists($directory)) {
$files = File::files('storage/'.$directory);
}
else {
$files = '';
}
Simply checking if the directory exists with the given lead ID, then if there are files uploaded either assign it the content, or set it blank (this is used for displaying an 'attachments' section on my page if not empty).
I'd like to create a .zip archive, upload it to Amazon S3, then delete the created .zip from the server. Steps 1 and 2 are working great, but the delete step is returning:
unlink(temp/file.zip): Resource temporarily unavailable
I've tried to unset all the related variables and resources, but I'm still getting the error.
Here's the code:
$zipFile = 'temp/file.zip';
// create the zip archive:
$z = new \ZipArchive();
$z->open($zipFile, \ZipArchive::CREATE);
$z->addEmptyDir('testdirectory');
// add a file
$filename = 'fileName.txt';
$content = 'Hello World';
$z->addFromString('testdirectory/' . $filename, $content);
$z->close();
// upload to S3
$s3 = AWS::createClient('s3');
$result = $s3->putObject(array(
'Bucket' => 'my-bucket-name',
'Key' => basename($zipFile),
'SourceFile' => $zipFile
));
// check to see if the file was uploaded
if ($result['#metadata']['statusCode'] == "200") {
$uploaded = true;
}
// delete the temp file
if ($uploaded) {
unset($result);
unset($s3);
unset($z);
if (file_exists($zipFile)) {
unlink($zipFile);
}
}
Some additional details: I'm using Lumen 5.4 and the aws-sdk-php-laravel package.
Any insight would be much appreciated! Thanks.
S3 is holding resources so we have to forcefully clear the gc (Garbage Collector).
Just do gc_collect_cycles() before deleting that file.
I'm tring upload large video file to my Amazon S3 bucket with aws api.
$uploader = new MultipartUploader($s3->getDriver()->getAdapter()->getClient(), $localFullFilePath, [
'bucket' => env('S3_BUCKET'),
'key' => $s3fullFullFilePath,
]);
try {
$result = $uploader->upload();
Log::info("Upload complete");
} catch (MultipartUploadException $e) {
Log::info($e->getMessage());
}
Then I am deleting my uploaded videos with below code.
foreach ($oldVideos as $oneVideo) {
// $localFullFilePath = $localFilePath . $oneVideo;
unlink($localFullFilePath);
}
My videos uploading successfully but when i try to delete my local file, it gives 'permission denied' error.
I am sure it is not file permission error because it occurs only when I uploading file to S3.
I think api does not fclose file after reading.
Do you suggest any tips or workarounds?
did you gave yourself permission in the map structure? That's also what happend to me last time :P
You must give yourself the permission to Upload & Delete
You're right, api does not close file. You can do it manually:
// open a file
$source = fopen($localFullFilePath, 'rb');
// pass a resource, not a path
$uploader = new MultipartUploader($s3->getDriver()->getAdapter()->getClient(), $source, [
'bucket' => env('S3_BUCKET'),
'key' => $s3fullFullFilePath,
]);
// upload
try {
$result = $uploader->upload();
Log::info("Upload complete");
} catch (MultipartUploadException $e) {
Log::info($e->getMessage());
}
// close
fclose($source);
// now we can remove it
I want to receive an image from an android device, which is sending an image as a Base64 encoded string. This is my controller action code:
public function Upload()
{
if ($this->request->is('post')) {
$dir= APP.'outsidefiles'; //chane directory for cloud
$fill = $this->request->data['File'] ;
$data = base64_decode($fill);
$im = imagecreatefromstring($data);
if ($im !== false)
{
$nam ='mypic.png';
move_uploaded_file($im['tmp_name'],$dir.DS.time().$nam);
}
//$dir= APP . 'outsidefiles';
// $this->request->data['Grade']['Fila']= $File;
$this->Grade->create();
if ($this->Grade->save($this->request->data))
{
$return = array(
'Response' =>'1',
'Body' => 'Data Saved');
return new CakeResponse(array('body' => json_encode($return, JSON_NUMERIC_CHECK)));
}
else
{
$return = array(
'Response' =>'0',
'Body' => 'Data not saved');
return new CakeResponse(array('body' => json_encode($return, JSON_NUMERIC_CHECK)));
}
}
}
However the image is not created in the destination folder - what is the error?
move uploaded file is for moving uploaded files
This will not work:
move_uploaded_file("I am not a file upload" , "/put/file/here/path.png");
It won't work even if the first argument points at a file because, as stated in the documentation:
If filename is not a valid upload file, then no action will occur, and move_uploaded_file() will return FALSE.
This prevents this kind of naïve attack from working:
// User input is not safe, it could be e.g.:
$_FILES['example']['tmp_name'] = '/etc/passwd';
...
move_uploaded_file(
$_FILES['example']['tmp_name'],
"/web/accessible/location/now-public.txt"
);
image create from string does not return an array
This also won't work:
$im = imagecreatefromstring($data);
$im['tmp_name']; <-
As, the return value from this function is an image resource, not an array. tmp_name related to file uploads - there is no actual file upload if it is being submitted as a base64 encoded string; it's just a string.
To upload a base64 encoded string means only creating a file
The logical steps required are not related to file uploads at all, only writing a binary string to a file i.e.:
$data = base64_decode($fill);
file_put_contents('/tmp/pic.png', $data);
I made Joomla admin component according to Joomla guide - http://docs.joomla.org/Developing_a_Model-View-Controller_Component/2.5/Developing_a_Basic_Component
In that i need to have file uploader which let user to upload single file.
In administrator\components\com_invoicemanager\models\forms\invoicemanager.xml i have defined
<field name="invoice" type="file"/>
In the controller administrator\components\com_invoicemanager\controllers\invoicemanager.php im trying to retrieve that file like below. But its not working (can't retrieve file)
Where am i doing it wrong ?
How can i get file and save it on disk ?
class InvoiceManagerControllerInvoiceManager extends JControllerForm
{
function save(){
$file = JRequest::getVar( 'invoice', '', 'files', 'array' );
var_dump($file);
exit(0);
}
}
make sure that you have included enctype="multipart/form-data" in the form that the file is being submitting. This is a common mistake
/// Get the file data array from the request.
$file = JRequest::getVar( 'Filedata', '', 'files', 'array' );
/// Make the file name safe.
jimport('joomla.filesystem.file');
$file['name'] = JFile::makeSafe($file['name']);
/// Move the uploaded file into a permanent location.
if (isset( $file['name'] )) {
/// Make sure that the full file path is safe.
$filepath = JPath::clean( $somepath.'/'.strtolower( $file['name'] ) );
/// Move the uploaded file.
JFile::upload( $file['tmp_name'], $filepath );}
Think i found the solution :)
$file = JRequest::getVar('jform', null, 'files', 'array');
Saving part is mentioned here - http://docs.joomla.org/Secure_coding_guidelines
For uploading the file from your component, you need to write your code in the controller file and you can extend the save() method. check the code given below -
public function save($data = array(), $key = 'id')
{
// Neccesary libraries and variables
jimport('joomla.filesystem.file');
//Debugging
ini_set("display_error" , 1);
error_reporting(E_ALL);
// Get input object
$jinput = JFactory::getApplication()->input;
// Get posted data
$data = $jinput->get('jform', null, 'raw');
$file = $jinput->files->get('jform');
// renaming the file
$file_ext=explode('.',JFile::makeSafe($file['invoice']['name'])); // invoice - file handler name
$filename = round(microtime(true)) . '.' . strtolower(end($file_ext));
// Move the uploaded file into a permanent location.
if ( $filename != '' ) {
// Make sure that the full file path is safe.
$filepath = JPath::clean( JPATH_ROOT."/media/your_component_name/files/". $filename );
// Move the uploaded file.
if (JFile::upload( $file['invoice']['tmp_name'], $filepath )) {
echo "success :)";
} else {
echo "failed :(";
}
$data['name'] = $filename ; // getting file name
$data['path'] = $filepath ; // getting file path
$data['size'] = $file['invoice']['size'] ; // getting file size
}
JRequest::setVar('jform', $data, 'post');
$return = parent::save($data);
return $return;
}
Joomla 2.5 & 3 style:
$app = JFactory::getApplication();
$input = $app->input;
$file= $input->files->get('file');
if(isset($file['name']))
{
jimport('joomla.filesystem.file');
$file['name'] = strtolower(JFile::makeSafe($file['name']));
$fileRelativePath = '/pathToTheRightFolder/'.$file['name'];
$fileAbsolutePath = JPath::clean( JPATH_ROOT.$fileRelativePath);
JFile::upload( $file['tmp_name'], $fileAbsolutePath );
}
http://docs.joomla.org/How_to_use_the_filesystem_package
has a full upload sample.
Little sample where admin choose the file type or all, enter the users to access the form upload. Folder to upload files in Joomla directory or with absolute path. Only selected users access the form upload.