create a bibtex archive with PHP - php

I'm trying to create a code that, based on informations from BD, creates a bibtex archive. That's what I got:
<?php
include("classe/conexao.php");
session_start();
$_SESSION[id_tese_especifica] = $_GET['id'];
$result = pg_query("SELECT titulo, id, data, autor_nome FROM teses ORDER BY data DESC");
$arr = pg_fetch_array($result);
echo "#phdthesis{phpthesis,
author={" . $arr[0] . "},
title={" . $arr[6] . " " . $arr[3] . "},
month={" . $arr[2] . "}";
$name = $_GET['id'] . ".bib";
$file = fopen($name, 'a');
$text = "test (it doesn't appears on archive and I don't know why, so I used the echo above and worked, but this is what should be on archive, or isn't?)";
fwrite($file, $text);
readfile($file);
fclose($fp);
header('Content-Disposition: attachment; filename="' . $file . '"');
header('Expires: 0');
?>
After that, it downloads an archive named 'Resource id #6', why? The name should be based on this: $name = $_GET['id'] . ".bib".
Thanks!

Because filename is stored in a $name variable in your code:
header('Content-Disposition: attachment; filename="' . $name . '"');
And $file variable is a resource, connected with open file.
And by the way - you don't close the file properly.
fclose($fp); // $fp is NOT defined, your pointer is in $file variable
Proper code for closing is:
fclose($file);
Next, rearrange your code.
First of all - headers should be sent BEFORE any output.
What you currently have is some mix of errors, which accidentally show you something that you want.
Proper code should be:
$name = $_GET['id'] . ".bib";
// first of all - set proper headers:
header('Content-Disposition: attachment; filename="' . $name . '"');
header('Expires: 0');
// next - do a query
$result = pg_query("SELECT titulo, id, data, autor_nome FROM teses ORDER BY data DESC");
$arr = pg_fetch_array($result);
// use echo for testing purposes only
// cause echo considered as a content of your file
echo "#phdthesis{phpthesis,
author={" . $arr[0] . "},
title={" . $arr[6] . " " . $arr[3] . "},
month={" . $arr[2] . "}";
$fp = fopen($name, 'a');
$text = "test (it doesn't appears on archive and I don't know why, so I used the echo above and worked, but this is what should be on archive, or isn't?)";
fwrite($fp, $text);
fclose($fp); // don't forget to close file for saving newly added data
readfile($name); // readfile takes a filename, not a handler.
die(); // end your script cause in other case all other data will be outputted too

Related

Greek letters in filename instead of full word

I'm using PHPSpreadsheet to export an html table to .xlsx file.
Everything works fine except...
I want to give the filename the greek fullname of the employee that is stored in a SESSION but I'm getting something like this:
2021_ΑΘΑΝΑΣΙΟΣ ΛΑΜΠΡΙΔΗΣ.xlsx
Is there a way I can set the actual name as the file name???
Edit: the code is
if(isset($_POST["file_content"]))
{
$temporary_html_file = './tmp_html/' . time() . '.html';
file_put_contents($temporary_html_file, $_POST["file_content"]);
$reader = IOFactory::createReader('Html');
$spreadsheet = $reader->load($temporary_html_file);
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$filename = $ecoYear . "_" . $_SESSION['fullname'] . '.xlsx';
$writer->save($filename);
header('Content-Type: application/x-www-form-urlencoded');
header('Content-Transfer-Encoding: Binary');
header("Content-disposition: attachment; filename=\"".$filename."\"");
readfile($filename);
unlink($temporary_html_file);
unlink($filename);
exit;
}
html_entity_decode — Convert HTML entities to their corresponding characters
<?php
$orig = "2021_ΑΘΑΝΑΣΙΟΣ ΛΑΜΠΡΙΔΗΣ.xlsx";
$text = html_entity_decode($orig);
echo $orig . PHP_EOL;
echo $text . PHP_EOL;
?>
Output: 72103715.php
2021_ΑΘΑΝΑΣΙΟΣ ΛΑΜΠΡΙΔΗΣ.xlsx
2021_ΑΘΑΝΑΣΙΟΣ ΛΑΜΠΡΙΔΗΣ.xlsx

Cant pass value as variable in this php script

Like the question says, I can't seem to pass a value in a variable in the following script. If I echo the variable, it exists as expected. If i copy and paste the echoed value into the code where $my_var is, it works. But it wont work with $my_var ?!?!?
Context- code requires another file to create a pdf, attaches it to an email and sends it, and then displays it in the browser. Have removed most of the code for brevity
$my_var = $_POST['quote_number'];
$filename = 'Quote_no' . $my_var . '.pdf';
$file = $_SERVER['DOCUMENT_ROOT'] . '/quotes/' . $filename ;
require('instant_quote.php');
function send_quote($my_var) {
//my_function code
};
send_quote($my_var);
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Accept-Ranges: bytes');
#readfile($file);
The syntax highlighting in your example was helpful, you have incorrect matching quotes:
$filename = "Quote_no' . $my_var . '.pdf";
... should be:
$filename = 'Quote_no' . $my_var . '.pdf';
Don't know why this worked, but it did...
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $file . '"');
header('Content-Length: ' . filesize($filename));
#readfile($filename);
Just removed the transfer encoding and accept-ranges from the headers, and it started accepting my variable as a value... go figure

Error in downloading.... The archived file is corrupted or damaged

My download.php is not working . After downloading is completed, the error on opening file is 'the archived file is corrupted or damaged '.
I dont know the reason of an error. so please help me. This code was a hard code. i tested this code by giving the name of the images. it worked right but when i retreived the images from database and tried to run this code , something went wrong.
<?php
echo "<br/>" , $product_id=$_REQUEST['product_id'];
echo "<br/>" , $query= ("SELECT image_name FROM " . $db_prefix ."product WHERE image_id = $product_id");
$test = class_exists('ZipArchive');
///$url='upload_images/';
$url = $_SERVER['DOCUMENT_ROOT'].'photohive/upload_images/';
$zip = new ZipArchive;
$zip->open($_SERVER['DOCUMENT_ROOT'].'photohive/downloads/file_' . time() . '.zip', ZipArchive::CREATE);
$result = mysql_query($query);
while( $row= #mysql_fetch_assoc($result))
{
//echo $url. $row['image_name'];
$file_name = $url.$row['image_name'];
if(file_exists($file_name)){
//$zip->addFile($file_name);
//$zip->addFromString(basename($file_name), file_get_contents($file_name));
$zip->addFile(realpath($file_name), $file_name);
}
}
$zip->close();
$encoding = 'binary';
$filename = $_SERVER['DOCUMENT_ROOT'].'photohive/downloads/file_' . time() . '.zip';
header('Pragma: public');
header('Expires: 0');
header('Content-Description: File Transfer');
header('Content-Disposition: filename="' . basename($filename). '"');
header('Content-Type: application/x-zip' );
header('Content-Transfer-Encoding: ' . $encoding);
header('Content-Length: ' . filesize($filename));
$file = readfile($filename);
//print($file);
exit;
?>
In your code you are using this string to get the filename twice: $_SERVER['DOCUMENT_ROOT'].'photohive/downloads/file_' . time() . '.zip';
In the second time, the time() probably will return the different timestamp, as some seconds will pass while you are compress the images.
Also using the time() method will bring the conflict on hi traffic sites, where you could have a possibility to get two or more requests in one second.
I suggest you to use the tempnam() function to generate the file. And remember to delete it after download is completed.
Here is a code:
$filename = tempnam($_SERVER['DOCUMENT_ROOT'].'photohive/downloads', "zip");
...
$zip->open($filename, ZipArchive::OVERWRITE);
And remove this line:
$filename = $_SERVER['DOCUMENT_ROOT'].'photohive/downloads/file_' . time() . '.zip';
after $encoding = 'binary';

Form downloads same ZIP over and over

Thanks to the users community on this forum, I wrote a very simple web form that allows my user to view text files from within their Internet browser.
I have now two functions whereby the text files returned by the search are compressed into a ZIP. Here's my code
function getFilesFromSite() {
$result = null;
$ZIPresult = null;
if (empty($_POST['DBSite'])) { return null; }
$mydir = MYDIR;
$dir = opendir($mydir);
$DBSite = $_POST['DBSite'];
$getfilename = mysql_query("select filename from search_table where site='" . $DBSite . "'") or die(mysql_error());
while ($row = mysql_fetch_array($getfilename)) {
$filename = $row['filename'];
$result .= '<tr><td>' . $filename . '</td></tr>';
$ZIPresult .= basename($mydir) . '/' . $filename.' ';
}
if ($result) {
$result = "<table><tbody><tr><td>Search Results.</td></tr> $result</table>";
shell_exec("/bin/rm -f SearchResult.zip;/usr/bin/zip -9 SearchResult.zip ". $ZIPresult ." > /dev/null ");
//header for forced download
header("Pragma: public");
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
$fileName = 'SearchResult.zip';
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Transfer-Encoding: binary");
header('Content-type: application/zip');
header("Content-length: " . filesize($fileName));
header('Content-Disposition: attachment; filename="' . $fileName . '"');
ob_start(); // Starts output buffering.
readfile($fileName); // "Outputs" the file.
$content = ob_get_flush(); // Grabs the output and assigns it to a variable.
print base64_encode($content);
}
function getFilesFromError() {
//Just a copy paste from above with different input parameter...
}
The problem is that the ZIP file with the contents from whatever search was done first gets downloaded over and over again. For instance, the results from getFilesFromSite() will always get downloaded even though I did a search with getFilesFromError() afterwards.
I suspect my headers are incorrectly set but I am not sure where.
PS: The new ZipArchive() library/class is not available on our production environment so I chose to use the Unix utility ZIP instead.
Using Base64 was actually not working for reasons well stated here. Instead, I turned zlib compression off and reverted back to using binary as output format. Finally, I set Content-Type to application/octet-stream in my header. Everything is working fine now ; here's my code:
function getFiles() {
ini_set('zlib.output_compression', 'Off');
$result = null;
$ZIPresult = null;
$cleanup = null;
$output = null;
$fileName = null;
//remove old zip if any
$cleanup = shell_exec("/bin/rm -f SearchResult.zip");
error_log("SHELL OUTPUT=>" . $cleanup, 0);
//test
if (empty($_POST['DBRIDs'])) { return null; }
$mydir = MYDIR; // set from the CONSTANT
$dir = opendir($mydir);
$DBRIDs = $_POST['DBRIDs'];
$getfilename = mysql_query("select /*! SQL_CACHE */ filename from automation where rid in (" . $DBRIDs . ")") or die(mysql_error());
while ($row = mysql_fetch_array($getfilename)) {
$filename = $row['filename'];
$result .= '<tr><td>' . $filename . '</td></tr>';
$ZIPresult .= basename($mydir) . '/' . $filename.' ';
}
if ($result) {
$result = "<table><tbody><tr><td>Search Results.</td></tr> $result</table>";
$output = shell_exec("/usr/bin/zip SearchResult.zip ". $ZIPresult ." ");
error_log("SHELL OUTPUT=>" . $output, 0);
$fileName = 'SearchResult.zip';
error_log("ZIP FILENAME=>" . $fileName, 0);
if (file_exists($fileName)) {
//header for forced download
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($fileName));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($fileName));
ob_clean();
flush();
readfile($fileName);
exit;
}
}
return $result;
}
Thanks to all for taking the time!!

Is the File Transfer code correct in my PHP?

I have this page that is supposed to be a download for a song. The download works in firefox for me but in chrome and safari nothing happens..here is my code
public function download() {
if (isset($this->request->get['order_download_id'])) {
$order_download_id = $this->request->get['order_download_id'];
} else {
$order_download_id = 0;
}
$download_info = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_download od LEFT JOIN `" . DB_PREFIX . "order` o ON (od.order_id = o.order_id) WHERE o.customer_id = '" . (int)$this->customer->getId(). "' AND o.order_status_id > '0' AND o.order_status_id = '" . (int)$this->config->get('config_download_status') . "' AND od.order_download_id = '" . (int)$order_download_id . "'");
if ($download_info->row) {
$file = DIR_DOWNLOAD . $download_info->row['filename'];
$mask = basename($download_info->row['mask']);
$mime = 'application/octet-stream';
$encoding = 'binary';
if (!headers_sent()) {
if (file_exists($file)) {
header('Pragma: public');
header('Expires: 0');
header('Content-Description: File Transfer');
header('Content-Type: ' . $mime);
header('Content-Transfer-Encoding: ' . $encoding);
header('Content-Disposition: attachment; filename="' . ($mask ? $mask : basename($file)) . '"');
header('Content-Length: ' . filesize($file));
$file = readfile($file, 'rb');
print($file);
} else {
exit('Error: Could not find file ' . $file . '!');
}
} else {
exit('Error: Headers already sent out!');
}
}
}
I have tried all kinds of different things to get this to work but nothing is happening in the two browsers...any ideas or help will be appreciated...
readfile returns the number of bytes sent, and needs not to be printed out. You should remove the line print($file);. Otherwise, you'll send more bytes than the Content-Length header specifies, and that will lead some HTTP clients to discard your answer.
Also, consider strange file names such as
"\r\nLocation: http://evil.com\r\n\r\n<script>alert('XSS');</script>
Are you handling that correctly?
See your syntax near
header('Content-Disposition: attachment; filename="'.$file_name_with_space. '"');
OR it can be
header("Content-Disposition: attachment; filename='".$file_name_with_space."'" );
Here the game is in Quotes only it will be treated as part of the string if it is written properly else will crash.
It works in all browser. IE, FF, Chrome, SAFARI I checked it personally so goahead.

Categories