Change Jquery file upload url dynamically - javascript

I am using jQuery File Upload in my project. I am having problem changing the URL dynamically i.e. I want to change the upload folder dynamically. I have seen some posts e.g.
jQuery File Upload: how to change the upload url dynamically
https://github.com/blueimp/jQuery-File-Upload/issues/2640
But these both tell to change "data.url" but data.url changes the folder where PHP files are uploaded.
I am able to solve this using sessions by changing these lines in upload handler.php from
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/',
'upload_url' => $this->get_full_url().'/files/',
to
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/'.$_SESSION['cid'].'/',
'upload_url' => $this->get_full_url().'/'.$_SESSION['cid'].'/',
But what happens if user has two different pages opened at a same time then it will upload all to the same folder because session variable wont be updated. Is there any possible solution to this using Javascript? so I wont need to worry about that. Any help will be much appreciated.
Thanks

The only solution is to solve it using sessions by changing these lines in upload handler.php from
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/',
'upload_url' => $this->get_full_url().'/files/',
to
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/'.$_SESSION['cid'].'/',
'upload_url' => $this->get_full_url().'/'.$_SESSION['cid'].'/',

This may not be the EXACT answer you might be looking for but following the steps can get you to your answer.
I had this kind of similar problem. I solved it by passing an extra variable to the script and change the upload_dir variable in php.
Your default index.php filw should look like this.
error_reporting(E_ALL | E_STRICT);
require('UploadHandler.php');
$upload_handler = new UploadHandler();
I modified it to listen for extra variable that I pass from JS. Look at the comments to see what is happening. Essentially what is happening is it makes sure that the extra variable called fuPath is received when call is made to this file (from javascript) and if not, do not upload the file. If the path is received then use it to get final destination based on web root directory.
error_reporting(E_ALL ^ (E_NOTICE | E_WARNING));
require('UploadHandler.php');
$urlHolder = NULL;
// This option will be used while uploading the file.
// The path will come as POST request.
if( isset($_POST['fuPath']) ) {
// perform validations to make sure the path is as you intend it to be
$urlHolder = filter_var($_POST['fuPath'], FILTER_SANITIZE_URL);
}
// This option will be used when deleting a file.
// The file details will come from GET request so have to be careful
else if( isset($_GET['fuPath']) ){
// perform validations to make sure the path is as you intend it to be
$urlHolder = filter_var($_GET['fuPath'], FILTER_SANITIZE_URL);
}
else{
exit;
}
$options = array(
'upload_dir'=> $_SERVER['DOCUMENT_ROOT'] .'/' .$urlHolder,
// 'upload_url'=>'server/php/dummyXXXX', // This option will not have any effect because thumbnail creation is disabled
'image_versions' => array(), // This option will disable creating thumbnail images and will not create that extra folder.
// However, due to this, the images preview will not be displayed after upload
);
if($urlHolder){
$upload_handler = new UploadHandler($options , true , null);
}
Now on JS side I have made the following changes.
var fullUpldPath = "";
// when file upload form is initialised then along with other options I also set the file upload path "fuPath".
// default will be empty string, so we can validate in php code.
$(localFormNames.fileForm).fileupload({
formData: {fuPath: fullUpldPath}
});
Now back to HTML. I have created a dummy button (lets call #uploadFiles) which user clicks to upload images. This is required because I want to manipulate this fuPath variable in between the time when user clicks to upload and upload starts. The plugin's upload button (lets call it #pluginButton) is hidden.
So when user click #uploadFiles, I change my file upload path as required. Set the modified variable and then click the actual plugin's upload button.
// ending / is mandatory.
fullUpldPath = "assets/uploadedImages" + $("#imagename").val() + "/";
$(localFormNames.fileForm).fileupload({
formData: {fuPath: fullUpldPath}
});
// Now manually trigger the file upload
$("#pluginButton").click();

I use user directories. See:
https://github.com/blueimp/jQuery-File-Upload/wiki/PHP-user-directories
index.php
require('UploadHandler.php');
class CustomUploadHandler extends UploadHandler {
protected function get_user_id() {
#session_start();
return $_SESSION['mySubDynamicDir'];
}
}
$upload_handler = new CustomUploadHandler(array(
'user_dirs' => true
));

Related

How should I delete a firebase storage file?

After attempting to delete a file I get the notification that it was successful. However, when I check the storage console page the document is still there.
If I manually specify the name of a file that was previously uploaded then that one will be deleted successfully.
Any idea what I'm doing wrong here? Is it somehow related to the fact that I just uploaded the file and now I'm deleting it? Is there some kind of cache on the storage ref that I have to query again in order for it to know that the new file exists?
I am following the documentation provided by Google here.
https://firebase.google.com/docs/storage/web/delete-files
Here is my code
const storage = firebase.storage();
const picture = storage.ref().child('images/' + file.name);
picture
.delete()
.then(function () {
notification.success({
message: 'File Deleted',
placement: 'bottomLeft',
});
})
.catch(function (error) {
console.error(error);
notification.warning({
message: 'There was an error',
placement: 'bottomLeft',
});
});
Update
When I say, "manually specifying the file" I mean that I can do this
const picture = storage.ref().child('images/alreadyUploadedImage.png');
Then run the same code to delete. This is why I asked about caching since it seems that if I reload my browser session by changing this text in my code that I can now delete a file. Also, this doesn't work for the file I just uploaded (before I refresh my browser). If I change the name in the code to, 'images/image.png' and then upload an image with that name and then immediately try to delete it, it doesn't work. But if I then refresh the browser and add another image, then delete that one, the 'image.png' file is gone from storage.
Here is a gif showing the file and firebase storage after the delete is complete on the client.
It turns out I was calling the put method again after I was calling the delete method. I'm using AntD and the Upload component, which has getValueFromEvent={normFile}. This, "normFile" function gets called every time a file is uploaded or removed. So I just had to return from that function if the event was, event.status === 'removed'.

React, Redux, Filepond

My question... how do I upload files using FilePond but onclick, not automatically like it does out of the box? Also, since I need to take a number of other actions with theses images (like display them for review prior to upload) and since I need to add other data to the FormData that gets sent (plus dispatch actions to Redux).
Normally I would create a FormObject append the files and other values to it before POSTing it to some endpoint (with any custom headers needed). However when I inspected the FilePond instance it seems like the only thing I have access to is a blob... not the actual files. Is this accurate? Do I need to follow some special FilePond specific technique to get file upload to work?
FilePond's docs have a custom config value called "server" that appears to have access to an actual file in the more advanced examples so is this the way it must be done? I can't just grab the files (from somewhere that I do not currently see on the FilePond instance) and append them to an object for use in my normal "service"?
Any tips are appreciated. In a React app I want to upload a variable number of files onclick after appending other form data and setting headers (using Axios, ideally) and POST these files to an API.
Example from their docs uses a prop like:
server="/api"
I want something like (fake code):
server={submitImages} <-- this should only happen onclick of some button
where:
submitImages = (fieldName, file) => {
const formData = new FormData()
formData.append(fieldName, file, file.name)
formData.append('foo', this.props.foo)
const docuploadresult = this.props.uploadDocs(formData) <-- a service that lives elsewhere and actually does the POST
docuploadresult.then(result => {
// success
}, error => {
// error
})
}
and my problems are that I don't see why this needs to happen in some special config object like server, don't see how to make this happen onclick, don't see an actual file anywhere.
I may be overthinking this?
FilePond offers the server property so it can handle the uploads for your. But this is not required, you can use getFiles to easily request all file items (and File objects) in FilePond and upload them yourself.
Add your own submit button to the form and use submitImages below to submit the files.
submitImages = (fieldName) => {
const formData = new FormData();
this.filepondRef.getFiles()
.map(fileItem => fileItem.file)
.forEach(file => {
formData.append(fieldName, file, file.name);
});
// upload here
}
If you want to show image previews you can add the image preview plugin.
https://pqina.nl/filepond/docs/patterns/plugins/image-preview/

How can I save a drag and dropped image to the server?

First of all, background.
Everything is behind a corporate firewall, so there is no showing a live version or accessing nifty tools like nodeJS or many libraries.
I have HTML, php 5, javascript, and jquery1.9.
I have an web window with a bunch of data. I want to allow users to be able to drop a picture called a sleuth image into a box, show that box, and save that image in a special location on my server. The sleuth image is a dynamically generated graph on a different internal server that I have no privileges whatsoever on (another department). While it could be named anything, I want to save it with a specific name so it displays properly later when the web window for this data is reloaded.
I have this javascript function which allows them to drop an image and displays it. I just need it to save the image to a .png.
function drop_handler(event) {
// this is part of the ability to drag sleuth images onto the OOC
// Prevent default behavior (Prevent file from being opened)
event.preventDefault();
var items = event.dataTransfer.items;
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.kind === 'string') {
item.getAsString(function(data) {
document.getElementById("sleuth").innerHTML = data;
});
}
}
}
I need to save the img src that show up in the variable "data" AS "sleuthImg.png"
Yes, I know I need to add validation. First, I need this part to work.
First, you will need an endpoint on the server that can accept files and store them. Assuming you have that part already, then:
Get the file from the dataTransfer object
https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/files
Then create a new FormData
https://developer.mozilla.org/en-US/docs/Web/API/FormData
var formData = new FormData();
formData.append('file', fileFromDataTransfer);
formData.append('mime_type', fileFromDataTransfer.type);
(where 'file' is the name of the post parameter that your server is expecting. 'mime_type' is another form data parameter included as an example)
Then, using the request-making library of your choosing, make a POST request with the form data.
post('your/upload/endpoint', formData);

Display FileName with fileUpload on Edit if file exists in a folder and filename in database in ASP.NET MVC

On Edit, how to assign filename (stored in SQL database as a string) to fileupload control.
Controller
public ActionResult editLeaveRequest(int id)
{
var model = hc.leaveRequests.Find(id);
if (!String.IsNullOrEmpty(model.documentUrl))
{
model.documentUpload.FileName = model.fName;
}
return View(model);
}
I've saved file in a folder and its filename(fName) in SQL database as string. What I'm trying to do is, check if filename(fName) exists in the database, if so, assign it to fileUpload's fileName and pass this model to ViewPage.
What I want is, display filename with the fileupload control as its status to inform user that there is a file already attached to this record and its filename is equal to filename(fName). But above code is giving following error:
Property or Indexer 'HttpPostedFileBased.FileName' cannot be assigned to -- it is read only`
Can someone please suggest how to accomplish it?
You should live with the fact that every time you reload your page, file upload input will be empty. What you need to do is:
Somehow show that the file exists, but in a separate block (e.g. <div>MyFile.png</div>)
Add file delete functionality as needed or do your model.documentUpload check to see if new file was posted and if it was, replace existing file with the new one.
Validate your form submit on the server-side to allow only one file per your entity.
You need to use another control to show currently FileName,
Only use HttpPostedFileBase at post time to upload a new file, maybe hide this control on client side and add button EDIT to show this control

how to fetch the current user data in phpfox

Topic: Fetch current user(some particular fields) data from the DB and display it on the Welcome Screen.
Explaination of UI : On the Registration Page, A dropdown would appear. As the user selects an option, it would trigger an event to fetch user image to show on the welcome page.
I have put following code in (pages.process) module
function getUserId($iUserId)
{
$aRows = $this->database()->select('p.image_path')->from($this->_sTable, 'p')
->Join(Phpfox::getT('user') , 'u', ' p.page_id = u.college_name') ->
where('u.college_name = p.page_id AND u.user_id = ' .
(int)$iUserId)->execute('getRows');
return $aRows;
}
The data will selected from User & Pages Table, and will be used to show the user image. Please suggest.
There is a service to get user details by is
$user_id = Phpfox::getUserId();
$aRow = Phpfox::getService('user')->getUser($user_id);
This will give you user details
For performance, check if the page you are altering already has the information you need, maybe you dont need to query the database in ajax if the page, when being created, already has that info and you can store it in javascript.
Since you mentioned an ajax situation (trigger an event on drop down to query the database), then you need to include a JS file (my suggestion since you can do this from a plugin), there are other ways but this is the best in my opinion.
Please read my article about plugins if you need help with writing one. My suggestion is to write a plugin to include your JS file in the page.
In the JS file you can call a "controller function" like this:
$.ajaxCall('mymodule.myfunction', 'param1=value1&param2=value2');
this would run the function "myfunction" in the file /module/mymodule/include/component/ajax/ajax.class.php
From this ajax file you can call "service functions" and send code to the browser, for example:
$value = Phpfox::getService('mmodule')->someOtherFunction();
$this->call('alert("' . $value . '");');
Hope it helps

Categories

Resources