I'm working with Moodle api functions and I want to get all grades for enrolled users in a specific course. The purpose is to print all grades in an excel file. I tried to get the data from gradereport_user_get_grade_items but its not working here is my php code.
<?php
require_once('./curl.php');
$course_id=4;
$domainname = '........'; //paste your domain here
$wstoken = 'e521817f5cf9798926e0563d452b7975';//here paste your getgradetoken
$wsfunctionname = 'gradereport_user_get_grade_items';
$restformat='xml';//REST returned values format
$grade = array( 'courseid' => $course_id , 'user_id'=> $user_id );
$user_grades = array($grade);
$params = array('user_grades' => $user_grades);
//REST CALL
header('Content-Type: text/plain');
$serverurl = $domainname . "/webservice/rest/server.php?wstoken=" . $wstoken . "&wsfunction=" . $wsfunctionname;
$curl = new curl;
//if rest format == 'xml', then we do not add the param for backwardcompatibility with Moodle < 2.2
$restformat = ($restformat == 'json')?'&moodlewsrestformat=' . $restformat:'';
$resp = $curl->post($serverurl . $restformat, $params);
print_r($resp);
//EXCEL
header("Content-Disposition: attachment; filename=\"gradereport.xls\"");
header("Content-Type: application/vnd.ms-excel;");
header("Pragma: no-cache");
header("Expires: 0");
$out = fopen("php://output", 'w');
foreach ($params as $data)
{
if (is_array($data)){
foreach ($data as $v) {
fputcsv($out, $v,"\t");
}
}
}
fclose($out);
?>
Related
I'm trying to export several tables from a database and creating a excel file for each table using PHP. The loop however is "bugged". Instead of creating a new file for each loop it just puts all data into the same file.
The code:
foreach ($pdo->query("SHOW TABLES;") as $allTables) {
$table = $allTables[0];
$allDataStmt = $pdo->prepare("SELECT * FROM $table;");
$allDataStmt->execute();
$fieldcount = $allDataStmt->columnCount();
$col_title = "";
$data = "";
for ($i = 0; $i < $fieldcount; $i++) {
$col = $allDataStmt->getColumnMeta($i);
$column = $col['name'];
$col_title .= '<Cell ss:StyleID="2"><Data ss:Type="String">' . $column . '</Data></Cell>';
}
$col_title = '<Row>' . $col_title . '</Row>';
while ($row = $allDataStmt->fetch(PDO::FETCH_NUM)) {
$line = '';
foreach ($row as $value) {
if ((!isset($value)) or ($value == "")) {
$value = '<Cell ss:StyleID="1"><Data ss:Type="String"></Data></Cell>\t';
} else {
$value = str_replace('"', '', $value);
$value = '<Cell ss:StyleID="1"><Data ss:Type="String">' . $value . '</Data></Cell>\t';
}
$line .= $value;
}
$data .= trim("<Row>" . $line . "</Row>") . "\n";
}
$data = str_replace("\r", "", $data);
header("Content-Type: application/vnd.ms-excel;");
header("Content-Disposition: attachment; filename=" . $table . ".xls");
header("Pragma: no-cache");
header("Expires: 0");
}
}
If I kill the loop after the first iteration it exports the data correctly from ONE table. If I let the loop run it just loads the same file with the data and the file becomes corrupted. I can't even open it in Excel.
What am I missing? Been stuck with this for hours.
Thank you!
What you are attempting with making multiple different attachments in the same HTTP request is not possible. The HTTP protocol does not have support for downloading multiple files. The most common workaround is to put the files in a zip archive for the client to download, so something like this:
$zip = new ZipArchive;
$zip_name = "excel_tables.zip";
if ($zip->open($zip_name, ZipArchive::CREATE|ZipArchive::OVERWRITE) === TRUE) {
foreach ($pdo->query("SHOW TABLES;") as $allTables) {
// (Your logic to build Excel file)
$file_content = $col_title . "\n" . $data;
$file_name = $table . ".xls";
file_put_contents($file_name, $file_content);
// Add file to the zip file
$zip->addFile($file_name);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=' . $zip_name);
header("Content-Length: " . filesize($zip_name));
header("Pragma: no-cache");
header("Expires: 0");
ob_clean();
flush();
readfile(__DIR__ . "/" . $zip_name);
}
hi im currently using a script which generates csv and sends its download link(destination) in a email. in the following code,the email is sent correctly but it does not generate the csv.
Code
$fileD = "Weekly_Report_From_".date('d-m-Y', strtotime('-1 week'))."_to_".date('d-m-Y').".csv";
$url_down = (Config_Reader::readProjectConfig('report')->exportDirectory.'/weeklyReport/'.$fileD);
echo "<br/>";
echo $url_down;
if(file_exists($url_down) == false){
echo "FILE DOES NOT EXISTs";
$fp = fopen($url_down, 'w');
$header = array("XX","XX","XX","XX","XX","XX","XX","XX","XX","XX");
fputcsv($fp, $header, ',');
foreach ($tables as $fields) {
fputcsv($fp, $fields,',');
}
}
else{ echo "FILE EXISTs";
$time_start = time();
$fileD = "Weekly_Report_From_".date('d-m-Y', strtotime('-1 week'))."_to_".date('d-m-Y')."#".$time_start.".csv";
$url_down = (Config_Reader::readProjectConfig('report')->exportDirectory.'/weeklyReport/'.$fileD);
$fp = fopen($url_down, 'w');
$header = array("XX","XX","XX","XX","XX","XX","XX","XX","XX","XX");
fputcsv($fp, $header, ',');
foreach ($tables as $fields) {
fputcsv($fp, $fields,',');
}
}
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Transfer-Encoding: binary");
fclose($fp);
$mail = new Zend_Mail ();
$sentFromEmail = $config->sentFrom_new;
$tr = new Zend_Mail_Transport_Sendmail ( '-f' . $sentFromEmail );
Zend_Mail::setDefaultTransport ( $tr );
$mail->setReturnPath($sentFromEmail);
$mail->setFrom ( $sentFromEmail, 'Reporters' );
$rty = "Hi,<br /><br />This system is working perfectly Report.";
$mail->setBodyHtml ( $rty );
$mail->addTo ( $weeklyReportRecipients );
$mail->setSubject ( "Weekly Report" );
try {
$mail->send ();
echo "success";
}
when i go in more detail. it always prints the file does not exist which is correct but it never makes the csv inside the directory,
I allowed all read write and excute permissions to the weeklyReport folder as well, but still no luck,, will any body be able to help me over this...
P.S $tables is the array that take use of to generate the csv... that works fine. and also $weeklyReportRecipients, $sentFromEmail are obtained from the config file and they are also working fine
I have written the following script which is to create a CSV file based on content from a Database. The script itself works perfectly and creates the CSV file and populates it as expected. The problem is that when the file downloads automatically it is empty, but when downloading it from the hosting server over FTP it is filled with the information.
Is the file just downloading too soon before the file is successfully written? Is there anything that can be done to fix this issue?
<?php
// Establish the MySQL Database Connection
include_once("./include/database.php");
include("functions.php");
$filename = 'devices.csv';
$headers = array('ID', 'Device', 'Name', 'Type', 'Scope', 'OS', 'Datacenter');
$handle = fopen($filename, 'w');
fputcsv($handle, $headers, ',', '"');
$sql = mysql_query("SELECT * FROM devices ORDER BY name ASC", $dp_conn);
while($results = mysql_fetch_object($sql))
{
$type = getDeviceType($results->type, $dp_conn);
$scope = getDeviceScope($results->scope, $dp_conn);
$os = getOS($results->os, $dp_conn);
$datacenter = getDatacenter($results->datacenter, $dp_conn);
$row = array(
$results->id,
$results->device_id,
$results->name,
$type,
$scope['name'],
$os,
$datacenter
);
fputcsv($handle, $row, ',', '"');
}
// rewind the "file" with the csv lines
fseek($handle, 0);
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
// make php send the generated csv lines to the browser
fpassthru($handle);
fclose($handle);
?>
After further testing and finding a similar post on the topic, I have found a fix. Rather than using fopen() on a file, I wrote the data to memory and it is now working correctly.
<?php
// Establish the MySQL Database Connection
include_once("./include/database.php");
include("functions.php");
$filename = 'devices.csv';
$headers = array('ID', 'Device', 'Name', 'Type', 'Scope', 'OS', 'Datacenter');
//$handle = fopen($filename, 'w');
$handle = fopen('php://memory', 'w');
fputcsv($handle, $headers, ',', '"');
$sql = mysql_query("SELECT * FROM devices ORDER BY name ASC", $dp_conn);
while($results = mysql_fetch_object($sql))
{
$type = getDeviceType($results->type, $dp_conn);
$scope = getDeviceScope($results->scope, $dp_conn);
$os = getOS($results->os, $dp_conn);
$datacenter = getDatacenter($results->datacenter, $dp_conn);
$row = array(
$results->id,
$results->device_id,
$results->name,
$type,
$scope['name'],
$os,
$datacenter
);
fputcsv($handle, $row, ',', '"');
}
// rewind the "file" with the csv lines
fseek($handle, 0);
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
// make php send the generated csv lines to the browser
fpassthru($handle);
fclose($handle);
?>
try putting this
// Establish the MySQL Database Connection
include_once("./include/database.php");
include("functions.php");
ob_start(); //start output buffering
$filename = 'devices.csv';
$headers = array('ID', 'Device', 'Name', 'Type', 'Scope', 'OS', 'Datacenter');
$handle = fopen($filename, 'w');
fputcsv($handle, $headers, ',', '"');
$sql = mysql_query("SELECT * FROM devices ORDER BY name ASC", $dp_conn);
while($results = mysql_fetch_object($sql))
{
$type = getDeviceType($results->type, $dp_conn);
$scope = getDeviceScope($results->scope, $dp_conn);
$os = getOS($results->os, $dp_conn);
$datacenter = getDatacenter($results->datacenter, $dp_conn);
$row = array(
$results->id,
$results->device_id,
$results->name,
$type,
$scope['name'],
$os,
$datacenter
);
fputcsv($handle, $row, ',', '"');
}
ob_end_clean(); //ending output buffering.
// rewind the "file" with the csv lines
fseek($handle, 0);
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
// make php send the generated csv lines to the browser
fpassthru($handle);
fclose($handle);
I have a webservice with a function like this
$app->get('/downloadPdf', function () use($app)
{
$log = 'example.pdf';
$res = $app->response();
$res['Content-Description'] = 'File Transfer';
$res['Content-Type'] = 'application/octet-stream';
$res['Content-Disposition'] ='attachment; filename=' . basename($log);
$res['Content-Transfer-Encoding'] = 'binary';
$res['Expires'] = '0';
$res['Cache-Control'] = 'must-revalidate';
$res['Pragma'] = 'public';
$res['Content-Length'] = filesize($log);
readfile($log);
});
Testing it with Advanced Rest Client works fine..
Question is .. how do i call it from my client with all the headers etc.
To specify more. I know there are a lot of examples on how to download a specific file by inserting its url into the curlopt_url with the complete address to the file. What i want is to let the webservice decide which file to return...
Thanks
Never got an answer .. so !!!
This is how i made it work....
Service Function can be seen below
$app->post('/downloadReport', 'authenticate', function() use ($app)
{
verifyRequiredParams(array('reportId'));
$body = $app->request()->getBody();
$params_str = urldecode($body);
$input = json_decode($params_str,true);
$report_id = $input['reportId'];
$db = new DbHandler();
$db->getReport($report_id);
$path = $db->getReportPdfPath($report_id);
$res = $app->response();
$res['Content-Description'] = 'File Transfer';
$res['Content-Type'] = 'application/octet-stream';
$res['Content-Disposition'] ='attachment; filename=' . basename($path);
$res['Content-Transfer-Encoding'] = 'binary';
$res['Expires'] = '0';
$res['Cache-Control'] = 'must-revalidate';
$res['Pragma'] = 'public';
$res['Content-Length'] = filesize($path);
readfile($path);
});
Called the function like this:
public function downloadReport($api_key,$id)
{
$curl_post_data = array('reportId' => $id);
$headers = array('Content-type: application/json','Authorization: '.$api_key,);
$fp = fopen (dirname(__FILE__) . '/localfile.tmp', 'w+');//This is the file where we save the information
$curl = curl_init(DONWLOAD_REPORT);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($curl_post_data));
curl_setopt($curl, CURLOPT_USERPWD, $api_key);
$file = curl_exec($curl);
if ($file === false)
{
$info = curl_getinfo($curl);
curl_close($curl);
die('error occured during curl exec. Additioanl info: ' . var_export($info));
}
curl_close($curl);
header('Content-type: ' . 'application/octet-stream');
header('Content-Disposition: ' . 'attachment; filename=report.pdf');
echo $file;
}
I have same problem with you,
I am using this code, and it works, return a pdf file from webservice.
$api = new RestClient(array(
'base_url' => 'http://another-webservice.com/',
'headers' => array(
'X-Token' => $res->headers->x_token,
'Accept' => 'application/pdf',
),
));
$result = $api->execute("reports/report",'GET', $params);
$filename = 'Report.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
echo $result->response;
References: How to display PDF in Browser
I'm using curl to fetch photos from Facebook url for authorized user, for each photo I'm adding it to a zip file to allow user to download whole album as zip.
if( !isset($_GET['id']) )
die("No direct access allowed!");
require 'facebook.php';
$facebook = new Facebook(array(
'appId' => 'removed',
'secret' => 'removed',
'cookie' => true,
));
if( !isset($_GET['id']) )
die("No direct access allowed!");
$params = array();
if( isset($_GET['offset']) )
$params['offset'] = $_GET['offset'];
if( isset($_GET['limit']) )
$params['limit'] = $_GET['limit'];
$params['fields'] = 'name,source,images';
$params = http_build_query($params, null, '&');
$album_photos = $facebook->api("/{$_GET['id']}/photos?$params");
if( isset($album_photos['paging']) ) {
if( isset($album_photos['paging']['next']) ) {
$next_url = parse_url($album_photos['paging']['next'], PHP_URL_QUERY) . "&id=" . $_GET['id'];
}
if( isset($album_photos['paging']['previous']) ) {
$pre_url = parse_url($album_photos['paging']['previous'], PHP_URL_QUERY) . "&id=" . $_GET['id'];
}
}
$photos = array();
if(!empty($album_photos['data'])) {
foreach($album_photos['data'] as $photo) {
$temp = array();
$temp['id'] = $photo['id'];
$temp['name'] = (isset($photo['name'])) ? $photo['name']:'photo_'.$temp['id'];
$temp['picture'] = $photo['images'][1]['source'];
$temp['source'] = $photo['source'];
$photos[] = $temp;
}
}
?>
<?php if(!empty($photos)) { ?>
<?php
$zip = new ZipArchive();
$tmp_file =tempnam('.','');
$file_opened=$zip->open($tmp_file, ZipArchive::CREATE);
foreach($photos as $photo) {
$url=$photo['source'];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$download_file=curl_exec($ch);
#add it to the zip
$file_added=$zip->addFile($download_file);
}
# close zip
$zip->close();
# send the file to the browser as a download
header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="albums.zip"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($tmp_file));
ob_clean();
flush();
readfile($tmp_file);
exit;
} ?>
problem: zip->open creates a file, zip->add returns 1 for each file added but the zip size is still 0 and readfile do not prompt for downloading.
At the moment, you're trying to do this:
foreach ($photos as $photo) {
$url = $photo['source'];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$download_file = curl_exec($ch);
$file_added = $zip->addFile($download_file);
}
This will not work because $dowload_file is a string and not a filename. You need to save your cURL parameter to a file, and pass the filename to $zip->addFile. If you look at PHP's documentation, it's expecting a filename, not a string:
The path to the file to add.
You need to do something like:
$temp_file = './temp_file.txt';
file_put_contents($temp_file, $download_file);
$file_added = $zip->addFile($temp_file);
// Delete after use
unlink($temp_file);