I am connecting to a 3rd party's API service to get a list of files attached to a given ticket. One of the calls is get_attachment.
call($client,'get_attachment',$data);
$client and $data are just info about connection and filename, etc...
the result is the actual file itself. if i print_r(call(....)), i get the file itself in my browser window. How can i present this to a user to download from my page? I would like to provide a hyper link, so the user can choose to click link and download this file.
foreach ($attachments as $id => $fileName){
echo "<a href='???'>".$fileName."</a>";
}
If i need to save the file locally that is fine, how would i go about referencing this file??
This is the only note i have for the 3rd party's api related to this call:
"This method will output file data for the specified attachment."
One approach to solving this is by calling the API on two separate requests, once to get the list, and another to download the file.
If your listing page ended up like the below, it would show the attachments, and clicking the link would open the attachment on a new tab and download the file
// include this at the top of your file before any other HTML is rendered.
if (isset($_GET['file')) {
// assuming $data will contain some reference to the filename now stored in $_GET['file']
echo call($client,'get_attachment',$data);
return;
}
// assuming $attachments contains the list of the files
foreach ($attachments as $id => $fileName){
echo "<a href='thisPage.php?file=" . $fileName . "'>" . $fileName . "</a>";
}
So your link ends up linking to the same page, but rather than rendering any HTML once someone clicks the link at the top of your script you would make the API call to get the file contents and then terminate the script (either return or exit will do the trick) - assuming you can call the contents of the file by its file name.
You may need to pass more than the filename, maybe the id? Whatever you need to make the API call for the attachment, you can pass through on the link.
Related
i have a download function receiving the filename by $_GET and i want to prevent users of downloading other files changing the path and accessing other files in the system.
method:
function actionDownload($arquivo) {
try {
$filepath = \Yii::getAlias('#webroot') . '/files/coordenadas/'. $arquivo;
if (file_exists($filepath)){
return \Yii::$app->getResponse()->sendFile(\Yii::getAlias('#webroot') . '/files/coordenadas/'. $arquivo, $arquivo);
}
}
catch (\Exception $exception) {
throw new NotFoundHttpException("Arquivo não encontrado");
}
}
the route to download the method:
http://example.com/converter-coordenadas/download?arquivo=geografica-utm-20200830171051.xlsx
if someone change the arquivo variable to another valid path it will be able to download other files. How prevent that, but keeping the function receiving the file name in a url param?
the situation that i have is:
the user upload a file through ajax
i convert this file and return the filename
create a download button with the link to the new file.
I don't have any other information to make a relation with the file, like an user id.
As #GetSet explained in the comments, the biggest problem is procedural. One way to do this correctly is as follows:
Upload the file to your server and save the reference in database (you already doing) and generate an unique ID for this file (or for this download). This ID will be saved in a database field, for example with the name: "donwload_id"
Then in the view (when you are creating the link for the download):
Html::a('Download', [Url::to('donwload-action'), 'download_id' => $model- >download_id]);
In your controller, You will know how to find the file by its unique identifier (download_id).
No one knows how you have generated this ID and therefore it is more difficult for anyone to be able to generate it again. Also you can limit the time available to download the file by setting an expiration date to the link.
I wanna create a few unique download link for my users. The reason is that I wanted to let them download once only, so that they can use back the same link to download again.
I've generate a few of the keys (example, qwertyasdfghzxcbn. As in the download link will be like www.xxxxx.com/download.php?qwertyasdfghzxcbn) in the database and flag field where when the user downloaded, it will update 1 to the flag field.
I did a search on the net and found this.
http://www.webvamp.co.uk/blog/coding/creating-one-time-download-links/
But that only works when you go to the page first then only the page will generate the unique link. I've already pre-generate the link inside my database, I don't need to regenerate again, if fact if I generate the key when user go the page, they will able to download multiple times by refreshing the page.
The solution would be to make the link target itself a PHP script.
You'd hide the actual file somewhere inaccessible from the browser (i.e., somewhere where you can reach the file via fopen(), but isn't within the document root), and put a download.php file to download files.
The download script itself would look something like this:
$fileid = $_REQUEST['file'];
$file = file_location($fileid); // you'd write this function somehow
if ($file === null) die("The file doesn't exist");
$allowed = check_permissions_for($file, $fileid) // again, write this
// the previous line would allow you to implement arbitrary checks on the file
if ($allowed) {
mark_downloaded($fileid, $file); // so you mark it as downloaded if it's single-use
header("Content-Type: application/octet-stream"); // downloadable file
echo file_get_contents($file);
return 0; // running a return 0; from outside any function ends the script
} else
die("You're not allowed to download this file");
Any link you point would simply point to download.php?fileid=712984 (whatever the fileid actually is). That would be the actual download link, since that script does transfer the file; but only if the user is allowed to retrieve it. You'd have to write the file_location(), check_permissions_for() and mark_downloaded() functions yourself though.
I would suggest using uniqid() function, and store unique ids with the expiration date in a database, while returning to the user url with something like this: ...?file_id=$id
When the link is being opened, you may delete it from the database or mark it to be deleted 'soon' (just in case user wants to refresh the page.)
This question is more about methodology than actual code - lines
I would like to know how to implement a pseudo caching (for lack of a better name) for FILES in php . I have tried to read some articles, but most of them refer to the internal caching system of PHP , and not to what I need which is a FILE cache.
I have several scenarios where I needed such a system applied :
Scenario 1 :
While accessing a post and clicking a link, all the post attachments are collected and added to a zip file for download.
Scenario 2 :
Accessing a post , the script will scan all the content , extract all links, download some matching images for each link (or dynamically prepare one) and then serve those to browser . (but not after checing expiration period ?? )
( Those example uses "post" and "attachment" because i use wordpress and it is wordpress terminology, both currently work for me fine, except they generate the file over and over again. )
My doubts regarding the two scenarios (especially No.2) - How do I prevent the script to do the operation EVERY time the page is accessed ? (in other words , if the file exists , just serve it without looping the whole creating operation again)
My first instinct was call the file with some distinctive (but not load - unique like uniqueid() ) name and then check if it is already on the server , but that presents several problems (like it can already exists as naming , but of another post ..) and also - that should be very resource intensive for a server with 20,000 images .
The second thing I thought was to somehow associate a meta data for those files, but then again, How to implement it ? How to knwo which link is of what image ??
Also, in a case where I check for the file existence on the server , how can I know if the file SHOULD be changed (and therefor recreated ) ?
Since I am refering to wordpress, I thought about storing those images as base64 from binary directly to the DB with the transien_API - but it feels quite clumsy.
To sum up the question . How to generate a file, but also know if it exists and call it directly when needed ?? does my only option is store the file-name in DB and associate it somehow with the post ?? that seems so non efficient ..
EDIT I
I decided to include some example code , as it can help people to understand my dilemma .
function o99_wbss_prepare_with_callback($content,$width='250'){
$content = preg_replace_callback( '/(http[s]?:[^\s]*)/i', 'o99_wbss_prepare_cb', $content );
return $content;
}
function o99_wbss_prepare_cb($match){
$url = $match[1];
$url = esc_url_raw( $url );//someone said not need ??
$url_name = parse_url($url);
$url_name = $url_name['host'];// get rid of http://..
$param = '660';
$url = 'http://somescript/' . urlencode($url) . '?w=' . $param ;
$uploads = wp_upload_dir();
//$uniqid = uniqid();
$img = $uploads['basedir'] . '/tmp/' . $url_name .'.jpg' ; // was with $uniqid...
if(! # file_get_contents($url)){
$url = 'path ' .$url. ' doesn"t exist or unreachable';
return $url;
} else {
$file = file_get_contents( $url );
}
// here I will need to make some chck if the file already was generated , and
// if so - just serve it ..
if ( $file) {
file_put_contents( $img, $file );
// Do some other operations on the file and prepare a new one ...
// this produces a NEW file in the wp-uploads folder with the same name...
unlink($img);
}
return $url;
}
For Scenario 1:
Wordpress stored all post attachments as posts in the posts table. When a post is accessed run a function either in a created plugin or your themes functions.php. Use the pre_get_posts hook check if you have already created the zip file with function file_exists() using a unique name for each zip archive you create, post ID or permalink would be a good idea. Although you would need to make sure there was no user specific content. You can use filemtime() to check the time the file was created and if it is still relevant. If zip file does not exist create it, pre_get_posts will pass the query object which has the the post ID, just grab all the post attachments using get_posts and the parent ID being set to the ID passed in the query object. The GUID field contains the URL for each attachment then just generate a zip archive using ZipArchive() following this tutorial at.
For Scenario 2:
If your wordpress templates are set up to use the wordpress functions then replace the attachment functions to return their url and map that to the new url you have the cached content. For example the_post_thumbnail() would go to wp_get_attachment_thumb_url() copy the file to your cache and use the cache url as output. If you wanted to cache the DOM for the page as well use ob_start(). Now just run a check at the start of the template using file_exists and filetime(), if both are valid read in the cached DOM instead of loading the page.
How do I find the filename of an image on a MediaWiki site?
I don't want to put the filename in manually. I need PHP code which will fetch me the filename.
I can use $f = wfFindFile( '$filename' ); but HOW DO I GET $filename?
I've been looking at the FILE class but I can't figure out how to use File::getFilename(); I keep getting an error call to undefined method.
What am I doing wrong?
Explaining in more detail:
I would like to add the pin it button to my site so when you click on the button it post it on the pin it board with the image and description of the image. I need to use php to send the image information so it works on every page on my site. I can't code the image name manually each time.
So far I have the code:
<img border="0" src="//assets.pinterest.com/images/PinExt.png" title="Pin It" />
Which works great except I need to put in a value for $f (image name). My question is how do I get the value of $f without having to put in in eg $f = wfFindFile( 'Sunset.jpg' );
I would have thought this would be a really common request for anyone trying to add pinterest to their site.
Thanks
The $filename you are looking for is basically how it is named in MediaWiki when it got uploaded, for example Landscape-plain.jpg. You will just use the wfFindFile() helper function to get a File object. Then call the methods:
$ php maintenance/eval.php
> $file = wfFindFile( 'Landscape-plain.jpg' );
> print $file->getName();
Landscape-plain.jpg
> print $file->getPath();
mwstore://local-backend/local-public/b/b0/Landscape-plain.jpg
> print $file->getFullPath();
/path/to/images/b/b0/Landscape-plain.jpg
> print $file->getTitle();
File:Landscape-plain.jpg
> exit
API documentation:
http://svn.wikimedia.org/doc/classFile.html
http://svn.wikimedia.org/doc/classLocalFile.html
EDIT BELOW
The file informations are available through a File object, so you definitely need to use wfFindFile() to get such an object.
To actually find the filename for the page the user is browsing on, you want to use the query context and get its title:
$context = RequestContext::getMain();
$t = $context->getTitle();
if( $title->getNamespace == 'NS_FILE' ) {
$filename = $title->getPrefixedText;
// do your stuff.
}
I want to upload a file on my PHP server. I am currently able to upload it on server using the following code but I don't know how I can store it on the server.
How can I store the file in a specific directory?
I also want the users to be able to download the files but only once they log in not before that.
For example i store the file in directory /myfiles no-one must be able to download it
unless he is logged in
e.g. someone can download the file if he knows the file location
like www.example.com/temp/myfile.txt
I don't want that - user must not be able to download it unless he is logged in.
I have one page B.php in which there will be the download link. When the user clicks on that link he must be able to download the file. In short, he must get a Save as/Open pop up of browser when he clicks my link. How do I do that?
Check the PHP documentation about move_uploaded_file() here: http://de.php.net/manual/en/function.move-uploaded-file.php
function UploadData()
{
$yourpath ="yourfoldername";
createafolder($yourpath ); // if not present then create it (its custom function)
$target_path = $yourpath . basename( $_FILES['fileupload']['name']);
if(move_uploaded_file($_FILES['fileupload']['tmp_name'], $target_path)) {
//write if any processing
}
else echo "Upload sucessful!";
}