mPDF - No PDF generated when called from within another function - php

I have a mail_merge function (using cakephp) which when called directly from the browser e.g.
domain.com/contacts/mail_merge will generate the PDF and save it to the server as needed with the database mapped fields.
When however I try to call this mail_merge function from another function. e.g. $this->mail_merge($cond, 1); The PDF won't generate. The database fields are still coming though to the mail_merge function so it's not this issue. Any idea why this might be happening? I have updated my code below to now include a simple generated txt file with the code I am trying to put onto the PDF and this works so there is simply something about mPDF that won't generate a PDF when called from a function.
Thanks
My mail_merge function is as follows:
// FUNCTION GENERATE MAIL MERGE - mPDF
// -------------------------------------------------------------->
function mail_merge($conditions=NULL, $mail_merge_id=1)
{
// REMOVE THE STANDARD LAYOUT
// ------------------------------------------------------>
$this->layout = null;
// GET THE CONTACTS
// ------------------------------------------------------------->
$contacts = $this->Contact->Card->find('all', array(
'limit' => 10,
//'fields' => $fields,
'contain' => array('Contact', 'Prospect', 'SaleDetail'),
'conditions' => $conditions
));
$this->set('contacts', $contacts);
// GE THE CONTENTS
// ------------------------------------------------------------>
$this->loadModel('MailMerge');
$content = $this->MailMerge->find('first', array(
'conditions' => array('MailMerge.id' => $mail_merge_id),
'fields' => array('MailMerge.description')
));
$this->set('content', $content);
// initializing mPDF
// --------------------------------------------------------------------------->
$this->Mpdf->init();
// RENDER THE VIEW AND SET AS A VARIABLE TO WRITE THE HTML
// --------------------------------------------------------------------------->
$response = $this->render('mail_merge');
$thebody = $response->body();
$this->Mpdf->WriteHTML($thebody);
// setting filename of output pdf file
// --------------------------------------------------------------------------->
$thefilename = "mail_merge_".date("d.m.Y_His").".pdf";
$this->Mpdf->setFilename(APP. WEBROOT_DIR . "/files/csv_exports/" . $thefilename);
// setting output to I, D, F, S
// --------------------------------------------------------------------------->
$this->Mpdf->setOutput('F');
// TEMP - CREATE TXT FILE ON THE SERVER
// ------------------------------------------------------------------------>
$thefilenametxt = "mail_merge_".date("d.m.Y_His").".txt";
$ourFileHandle = fopen(APP. WEBROOT_DIR . "/files/csv_exports/" . $thefilenametxt, 'w');
fwrite($ourFileHandle, $thebody);
fclose($ourFileHandle);
return $thefilename;
} // END MAIL MERGE

I discovered the issue lied with the setOutput function of the component.
When I changed:
$this->Mpdf->setFilename(APP. WEBROOT_DIR . "/files/csv_exports/" . $thefilename);
$this->Mpdf->setOutput('F');
To
$this->Mpdf->Output(APP. WEBROOT_DIR . "/files/csv_exports/" . $thefilename, 'F');
it worked as needed.

Related

Download a zip file that is created when a URL is passed to domain site, but I have tried for 4 days 30-50 different ways, and no luck. CAISO OASIS

The site is the CAISO OASIS and they use an old way of querying and returning datasets. 30 days at a time, zip file with enclosed *.csv files. I have tried for 4 days coming up with a way to automate this download first of the zip file but i cant even get past there.
If I populate the url string I want and enter it myself in the address bar a zip file will start downloading, I cannot for the life of me get it to do the same through code.
I need to use php to accomplish this task.
I have tried, fopen, file_get_contents, file_put_contents, cURL, ziparchive class. I have tried changing all sorts of things. The best I get is a download of a corrupt zip file that is empty.
Ideally i would love to extract the *.csv or xml file but I cannot even do the first basic step.
The following variable I populate, $url_caiso_qry, if you take the echo string and past in the browser and enter the zip file will start downloading, but I cannot download it automatically.
http://oasis.caiso.com/oasisapi/SingleZip?startdatetime=20220109T7:00-0000&enddatetime=20220207T7:00-0000&resultformat=6&queryname=SLD_FCST&market_run_id=ACTUAL&version=1
<?php
$public_end = strpos($_SERVER['SCRIPT_NAME'], '/public') + 13;
$doc_root = substr($_SERVER['SCRIPT_NAME'], 0, $public_end);
define("WWW_ROOT", $doc_root);
// creates data array for precio de carga SIN
// function create_dataarrayp_chrt($zona) {
$ayer = date("Ymd\T7:00-0000", strtotime('now - 1 day'));
$mespasado = date("Ymd\T7:00-0000",strtotime('-30 days'));
$sdate = $mespasado; //startdatetime=
$edate = $ayer; //enddatetime=
$resultformat = '6';
$queryname='SLD_FCST';
$version='1';
$marketrunid='ACTUAL';
$fields = [
'startdatetime' => $sdate,
'enddatetime' => $edate,
'resultformat' => $resultformat,
'queryname' => $queryname,
'market_run_id' => $marketrunid,
'version' => $version,
];
//post fields
$postparam = urldecode(http_build_query($fields));
//PRECIOS url base string
$urlcaiso = 'http://oasis.caiso.com/oasisapi/SingleZip?';
//$urlcaiso = 'http://oasis.caiso.com/oasisapi/SingleZip?resultformat=6&queryname=SLD_FCST&version=1&market_run_id=ACTUAL&startdatetime=' . $sdate . 'T07:00-0000&enddatetime=' . $edate . 'T07:00-0000';
$url_caiso_qry = $urlcaiso . $postparam;
$caisofile = file_get_contents($url_caiso_qry, "rb");
//attempt to write file to destination path, but no file is written. Instead the following warning
//Warning: file_put_contents(/name1/name2/private/test/):
// failed to open stream: No such file or directory in C:\xampp\htdocs\name1\name2\private\test.php on line 94
$destination_path = WWW_ROOT . 'name2/private/test/';
$newfile = file_put_contents($destination_path, $caisofile);
echo $newfile . '<br><br>';
?>
The second parameter you pass to file_get_contents describes the use_include_path according to the php documentation.
I tried this simple example to get the file and save it:
<?php
$content = file_get_contents('http://oasis.caiso.com/oasisapi/SingleZip?startdatetime=20220109T7:00-0000&enddatetime=20220207T7:00-0000&resultformat=6&queryname=SLD_FCST&market_run_id=ACTUAL&version=1');
file_put_contents('example.zip', $content);
Running file example.zip gives the following output:
example.zip: Zip archive data, at least v2.0 to extract which indicates success.
So essentially your final code could look something like this:
<?php
// Build url here
$url = 'http://oasis.caiso.com/...';
// Download file
$zipFile = file_get_contents($url);
$public_end = strpos($_SERVER['SCRIPT_NAME'], '/public') + 13;
$doc_root = substr($_SERVER['SCRIPT_NAME'], 0, $public_end);
define("WWW_ROOT", $doc_root);
$targetPath = WWW_ROOT . 'proj3-ampenergy/private/test/'; // This could be any other path where your file should be stored
// Write contents to file
file_put_contents($targetPath, $zipFile);
// Write extraction logic here
Clean & tested code. Your csv file will be extracted to your script's directory.
<?php
define('PATH_ZIP', __DIR__ . '/archive.zip');
$url = 'http://oasis.caiso.com/oasisapi/SingleZip?' . http_build_query
([
'startdatetime' => '20220109T7:00-0000',
'enddatetime' => '20220207T7:00-0000',
'resultformat' => '6',
'queryname' => 'SLD_FCST',
'market_run_id' => 'ACTUAL',
'version' => '1',
]);
$data = file_get_contents($url);
file_put_contents(PATH_ZIP, $data);
$zip = new ZipArchive;
if ($zip->open(PATH_ZIP) === true)
{
$zip->extractTo(__DIR__);
$zip->close();
}

Saving html page in local storage using php

I am using PDFTOHTML (a php library) to convert pdf files to html and it's working fine but it's showing converted file in a browser and not storing in local folder, i want to store converted html in local folder using php with the same name as pdf was i-e mydata.pdf to mydata.html
Code that is converting pdf to html is:-
<?php
// if you are using composer, just use this
include 'vendor/autoload.php';
$pdf = new \TonchikTm\PdfToHtml\Pdf('cv.pdf', [
'pdftohtml_path' => 'C:/wamp64/www/new/poppler-0.51/bin/pdftohtml.exe',
'pdfinfo_path' => 'C:/wamp64/www/new/poppler-0.51/bin/pdfinfo.exe'
]);
// get content from all pages and loop for they
foreach ($pdf->getHtml()->getAllPages() as $page) {
echo $page . '<br/>';
}
?>
Just change your foreach to
$filePdf = 'cv'; // your pdf filename without extension
$pdf = new \TonchikTm\PdfToHtml\Pdf($filePdf.'.pdf', [
'pdftohtml_path' => 'C:/wamp64/www/new/poppler-0.51/bin/pdftohtml.exe',
'pdfinfo_path' => 'C:/wamp64/www/new/poppler-0.51/bin/pdfinfo.exe'
]);
$counterPage = 1;
foreach ($pdf->getHtml()->getAllPages() as $page) {
$filename = $filePdf . "_" . $counterPage.'.html'; // set as string directory and filename where you want to save it
if (file_exists($filename)) {
// if file exist do something
} else {
// else
$fileOpen = fopen($filename, 'w+');
fputs($fileOpen, $page);
fclose($fileOpen);
}
$counterPage++;
echo $page . '<br/>';
}
This will create you file for example: example_1.html, example_2.html and so on.
if this not help you then probably you need to use file_put_contents with ob_start() and ob_get_contents() read more here
Look this :
<?php
// if you are using composer, just use this
include 'vendor/autoload.php';
$pdf = new \TonchikTm\PdfToHtml\Pdf('cv.pdf', ['pdftohtml_path' => 'C:/wamp64/www/new/poppler-0.51/bin/pdftohtml.exe', 'pdfinfo_path' => 'C:/wamp64/www/new/poppler-0.51/bin/pdfinfo.exe']);
// get content from all pages and loop for they
$file = fopen('cv.html', 'w+');
$data = null;
foreach ($pdf->getHtml()->getAllPages() as $page) {
$data .= "".$page."<br/>";
}
fputs($file, $data);
fclose($file);
I did not test this code

edit docx file using phpword

is it possible to edit existing docx file using phpword?
i want to add footer text to my existing docx file.
there are lot of examples but those examples are creating the doc file from scratch not editing the file
can someone link to me an example? thank you
just like this.
<?php
require_once 'PHPWord.php';
// New Word Document
$PHPWord = new PHPWord();
// New portrait section
$section = $PHPWord->createSection();
// Add header
$header = $section->createHeader();
$table = $header->addTable();
$table->addRow();
$table->addCell(4500)->addText('This is the header.');
$table->addCell(4500)->addImage('_earth.jpg', array('width'=>50, 'height'=>50, 'align'=>'right'));
// Add footer
$footer = $section->createFooter();
$footer->addPreserveText('Page {PAGE} of {NUMPAGES}.', array('align'=>'center'));
// Write some text
$section->addTextBreak();
$section->addText('Some text...');
// Save File
$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007');
$objWriter->save('HeaderFooter.docx');
?>
Yes you can edit.
From documentation
PHPWord is a library written in pure PHP that provides a set of
classes to write to and read from different document file formats. The
current version of PHPWord supports Microsoft Office Open XML (OOXML
or OpenXML), OASIS Open Document Format for Office Applications
(OpenDocument or ODF), and Rich Text Format (RTF).
Actually this is the procedure
Load our existing file as template.
Edit
Save
From the Documentation, I found an example,
<?php
include_once 'Sample_Header.php';
// Template processor instance creation
echo date('H:i:s'), ' Creating new TemplateProcessor instance...', EOL;
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('resources/Sample_07_TemplateCloneRow.docx');
// Variables on different parts of document
$templateProcessor->setValue('weekday', htmlspecialchars(date('l'))); // On section/content
$templateProcessor->setValue('time', htmlspecialchars(date('H:i'))); // On footer
$templateProcessor->setValue('serverName', htmlspecialchars(realpath(__DIR__))); // On header
// Simple table
$templateProcessor->cloneRow('rowValue', 10);
$templateProcessor->setValue('rowValue#1', htmlspecialchars('Sun'));
$templateProcessor->setValue('rowValue#2', htmlspecialchars('Mercury'));
$templateProcessor->setValue('rowValue#3', htmlspecialchars('Venus'));
$templateProcessor->setValue('rowValue#4', htmlspecialchars('Earth'));
$templateProcessor->setValue('rowValue#5', htmlspecialchars('Mars'));
$templateProcessor->setValue('rowValue#6', htmlspecialchars('Jupiter'));
$templateProcessor->setValue('rowValue#7', htmlspecialchars('Saturn'));
$templateProcessor->setValue('rowValue#8', htmlspecialchars('Uranus'));
$templateProcessor->setValue('rowValue#9', htmlspecialchars('Neptun'));
$templateProcessor->setValue('rowValue#10', htmlspecialchars('Pluto'));
$templateProcessor->setValue('rowNumber#1', htmlspecialchars('1'));
$templateProcessor->setValue('rowNumber#2', htmlspecialchars('2'));
$templateProcessor->setValue('rowNumber#3', htmlspecialchars('3'));
$templateProcessor->setValue('rowNumber#4', htmlspecialchars('4'));
$templateProcessor->setValue('rowNumber#5', htmlspecialchars('5'));
$templateProcessor->setValue('rowNumber#6', htmlspecialchars('6'));
$templateProcessor->setValue('rowNumber#7', htmlspecialchars('7'));
$templateProcessor->setValue('rowNumber#8', htmlspecialchars('8'));
$templateProcessor->setValue('rowNumber#9', htmlspecialchars('9'));
$templateProcessor->setValue('rowNumber#10', htmlspecialchars('10'));
// Table with a spanned cell
$templateProcessor->cloneRow('userId', 3);
$templateProcessor->setValue('userId#1', htmlspecialchars('1'));
$templateProcessor->setValue('userFirstName#1', htmlspecialchars('James'));
$templateProcessor->setValue('userName#1', htmlspecialchars('Taylor'));
$templateProcessor->setValue('userPhone#1', htmlspecialchars('+1 428 889 773'));
$templateProcessor->setValue('userId#2', htmlspecialchars('2'));
$templateProcessor->setValue('userFirstName#2', htmlspecialchars('Robert'));
$templateProcessor->setValue('userName#2', htmlspecialchars('Bell'));
$templateProcessor->setValue('userPhone#2', htmlspecialchars('+1 428 889 774'));
$templateProcessor->setValue('userId#3', htmlspecialchars('3'));
$templateProcessor->setValue('userFirstName#3', htmlspecialchars('Michael'));
$templateProcessor->setValue('userName#3', htmlspecialchars('Ray'));
$templateProcessor->setValue('userPhone#3', htmlspecialchars('+1 428 889 775'));
echo date('H:i:s'), ' Saving the result document...', EOL;
$templateProcessor->saveAs('results/Sample_07_TemplateCloneRow.docx');
echo getEndingNotes(array('Word2007' => 'docx'));
if (!CLI) {
include_once 'Sample_Footer.php';
}
Now see the lines of code given below , how to access existing header and footer
$headers = $section->getHeaders();
$header1 = $headers[1]; // note that the first index is 1 here (not 0)
$elements = $header1->getElements();
$element1 = $elements[0]; // and first index is 0 here normally
// for example manipulating simple text information ($element1 is instance of Text object)
$element1->setText("adding text here - old part: " . $element1->getText());
$footers = $section->getFooters(); // to access footer
You can find more examples here . If you want to add more styles, please read this page. And you can also see some recipes in their documentation.
In the footer of your file(template) docx, you can put a variable like this ${var1}.
Open a file as template with "TemplateProcessor".
$templateObject = new TemplateProcessor($filename);
Replace var1 variable in your file
$templateObject->setValue('var1', 'test');
Transform your template into a PhpWord
$fileName = $templateObject->save();
$phpWordObject = IOFactory::load($fileName);
unlink($fileName);
return $phpWordObject;
Save/Render your phpWord instance
// create the writer
$writer = $this->wordService->createWriter($phpWordObject, 'Word2007');
// create the response
$response = $this->wordService->createStreamedResponse($writer);
// adding headers
$dispositionHeader = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
'export.docx'
);
$response->headers->set('Content-Type', 'application/msword');
$response->headers->set('Pragma', 'public');
$response->headers->set('Cache-Control', 'maxage=1');
$response->headers->set('Content-Disposition', $dispositionHeader);
Might be useful for Laravel 5 users. You can use this in your controllers.
public function wordDocumentFromWordTemplate() {
$templateFile = public_path('templates') . '/template-file.docx';
$templateObject = new TemplateProcessor($templateFile);
$templateObject->setValue('var1', 'Text for var1');
$wordDocumentFile = $templateObject->save();
$headers = [
'Content-Type' => 'application/msword',
'Cache-Control' => 'max-age=0'
];
return response()->download($wordDocumentFile, 'result.docx', $headers);
}

How to save a image filecontent into the SQL database using eloquent?

I'm getting confused about how to save an image content inside of a database table.
Please see the fourth line of code. I'm sure that this restful method (using POST) is working because getSize() returns the true value.
Also, if I debug what returns the 5th line I get something like the next one:
So, I'm not sure if what am I missing to save this data into the database.
$personId = Input::get('PersonId');
$file = Input::file('media');
$tmppath = $file->getRealPath();
$content = file_get_contents($tmppath); //$file->getSize();
// return $content;
$model = Person::find($personId);
$model->Photo = $content;
$model->save();
$result = array(
"success" => true,
"data" => $personId,
"error" => ""
);
You need to save the file to the server and only store the path in the database.
Write an appropriate method, ideally you can store it in a trait.
private function saveFileToDisk($file, $fileName)
{
$path = public_path() . '/uploads/';
return $file->move($path, $fileName . $file->getClientOriginalExtension());
}
An then pass the file input to your method and provide a name for the file:
$model->Photo = $this->saveFileToDisk(Input::file('media'), $model->Name);
Obvisouly you need to validate you input before all this.

php: equivalent of $_FILES upload?

I have to send a file to an API. The API documentation provides an example of how to do this through a file upload script ($_FILES). But, I have the files on the same machine, so would like to skip this step and just read in the file directly to save time.
How can I read in the file (a video) so that it will work with this code snippet?
I understand that FILES is an array, but I could set the other parts of it (the filename) seperately, I just really need the data part of it to be read in the same format to work with this code (do I use fread? file get contents?)
<?php
# Include & Instantiate
require('../echove.php');
$bc = new Echove(
'z9Jp-c3-KhWc4fqNf1JWz6SkLDlbO0m8UAwOjDBUSt0.',
'z9Jp-c3-KhWdkasdf74kaisaDaIK7239skaoKWUAwOjDBUSt0..'
);
# Create new metadata
$metaData = array(
'name' => $_POST['title'],
'shortDescription' => $_POST['shortDescription']
);
# Rename the video file
$file = $_FILES['video'];
rename($file['tmp_name'], '/tmp/' . $file['name']);
$file_location = '/tmp/' . $file['name'];
# Send video to Brightcove
$id = $bc->createVideo($file_location, $metaData);
?>
Thanks in advance for any help!
Er - all you'd need to do is feed the location, not a file handle or anything, no?
$files = $_FILES['video'];
$filename = $files['name'];
$file_location = '/home/username/' . $filename; // maybe append the extension
$id = $bc->createVideo($file_location, $metaData);
Or more simply
$id = $bc->createVideo( '/foo/bar/baz.txt', $metaData );
Looks like you don't need to do anything except point at the file on your local disk. What about:
<?php
# Include & Instantiate
require('../echove.php');
$bc = new Echove(
'z9Jp-c3-KhWc4fqNf1JWz6SkLDlbO0m8UAwOjDBUSt0.',
'z9Jp-c3-KhWdkasdf74kaisaDaIK7239skaoKWUAwOjDBUSt0..'
);
# Create new metadata
$metaData = array(
'name' => $_POST['title'],
'shortDescription' => $_POST['shortDescription']
);
# point at some file already on disk
$file_location = '/path/to/my/file.dat'; // <== if the file is already on the box, just set $file_location with the pathname and bob's yer uncle
# Send video to Brightcove
$id = $bc->createVideo($file_location, $metaData);

Categories