We are using Cake's E-Mail class to send emails with attachments. It works fine for all cases except one and we are not able to figure out where the problem is.
Process:
A pdf-File is created & written to the file-system (file is written correctly and exists)
when the Email is sent the attachment is 0bytes in size (whereas the file to attach is created correctly in the file-system)
Working code:
// Write invoice as file
$CakePdf->write(APP . 'tmp' . DS . 'invoices' . DS . $invoiceNo . '.pdf');
[...]
// Send invoice to customer
$Email = new CakeEmail('invoice');
$Email->attachments(APP . 'tmp' . DS . 'invoices' . DS . $invoiceNo . '.pdf');
$Email->to($this->Invoice->Customer->getEmailAdress($customerId));
$Email->viewVars(array('invoice_no' => $invoiceNo));
$Email->send();
Not working code (attachment is zero bytes in size):
$CakePdf->write(APP . 'tmp'. DS .'certificates' . DS . $certLoginId . $certCourseId . '.pdf');
[...]
// Send certificate to customer
$Email = new CakeEmail('certificate');
$Email->attachments(APP . 'tmp'. DS .'certificates' . DS . $certLoginId . $certCourseId . '.pdf');
$Email->to($emailOfUser);
$Email->viewVars(array('courseName' => $certCourseName, 'probandName' => $probandName));
$Email->send();
Edit - there is no typo it is all correctly set. The problem seems to be, that the generation of a PDF by tcpdf runs asycnronously in the background. So when Cake tries to attach the file it is not written to the file system completly. So it cannot be attached.
If tried to let the script sleep for a while with no success:
echo '<br>';
echo $path_to_certificate;
echo '<br>';
echo filesize($path_to_certificate);
sleep(10);
echo '<br>';
echo $path_to_certificate;
echo '<br>';
echo filesize($path_to_certificate);
echo '<br>';
sleep(10);
echo $path_to_certificate;
echo '<br>';
echo filesize($path_to_certificate);
Outputs:
C:\xampp\htdocs\www\eflux_frontend\app\tmp\certificates\13750.pdf
0
C:\xampp\htdocs\www\eflux_frontend\app\tmp\certificates\13750.pdf
0
C:\xampp\htdocs\www\eflux_frontend\app\tmp\certificates\13750.pdf
0
Whereas the file is generated in the meantime, because I can see & access the file in the filesystem. It isn't a locking Problem because the other code works in a different place, but the file generated is smaller so it does not take up so much time to process.
How can I now ensure that the generation process is complete?
It seems that we are not able to ensure, that the PDF is properly created before attaching it to an email (maybe someon can give me a hand here).
Due to the fact, that the created PDF is written to a database an ugly workaround is possible: After the PDF is written to database, we can take it out of the database, write a file using the CakeFileHandler and attach this to the email which works for me:
// Workaround
$this->Certificate->recursive = -1;
$data = $this->Certificate->findById($cert_id);
$pdf = base64_decode($data['Certificate']['certificate_pdf']);
$path_to_certificate = APP . 'tmp'. DS .'certificates' . DS . $certLoginId . $certCourseId . '.pdf';
$certificate_file = new File($path_to_certificate);
$certificate_file->write($pdf);
[do mail stuff]
$certificate_file->delete();
$certificate_file->close();
Related
I am just trying to check if an image exists or not, I can do it by using PHP. For example:-
$file = WWW_ROOT .'uploads' . DS . 'employee' . DS .'_'.check.jpg;
$file_exists = file_exists($file);
It's working fine for me. But I have tried also tried using elementExists like this:-
if($this->elementExists("../".$employees->front_image))
{
echo $this->Html->image("../".$employees->front_image); // image output fine without condition.
}
// Here $employees->front_image = uploads/employee/employeename.jpg
This check is not working. How can I do this in CakePHP?
CakePHP is written in PHP, so if you already have a simple solution like file_exists() use that. So you can write something like this:-
if (file_exists(WWW_ROOT . $employees->front_image)):
echo $this->Html->image('../' . $employees->front_image);
endif;
elementExists() is intended for checking that a View element exists, not if files exist in the webroot, so should not be used like you are trying. It does do a file_exists() check, but this scans all available View element paths only.
I think this works in Cake 3 (you should do this in afterFind method IMO):
// Create a new file with 0644 permissions
$file = new File('/path/to/file.php', true, 0644);
if ($file->exists()) {
//do something
}
$file->close();
Your way is checking whether view element exists or not.
This worked for me:
Q: How to check if image exists on remote url or not?
Explanation:
$rfile will take url
$check will open the file with read rights
If file exists then it will print "File exists" else "Doesn't exists".
code:
<?php
// Remote file url
$rFile = 'https://www.example.com/files/test.pdf';
// Open the file
$check = #fopen($rFile, 'r');
// Check if the file exists
if(!$check){
echo 'File does not exist';
}else{
echo 'File exists';
}
?>
On the same project i'm using phpExcel to generate excel files just fine.
PHPExcel files location:
C:\wamp\www\circulo\app\Vendor\PHPExcel\ (this folder contains PHPExcel.php along with PHPExcel files folder)
Also on the same project, i'm using dompdf alone to generate pdf file just fine (not via PHPExcel). I've just liked a lot how PHPExcel allows excel file construction so i'd like to create pdfs via PHPExcel as well.
dompdf files location:
C:\wamp\www\circulo\app\Vendor\dompdf\
The path seems correct via debugger => C:\wamp\www\circulo\app\Vendor\dompdf\dompdf.php
This is my code to get a pdf file:
I get error:
[PHPExcel_Writer_Exception] Unable to load PDF Rendering library
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');
require_once APP . DS . 'Vendor' . DS . 'PHPExcel' . DS . 'PHPExcel.php';
$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;
$rendererLibrary = 'dompdf.php';
$rendererLibraryPath = APP . 'Vendor' . DS . 'dompdf' . DS .$rendererLibrary;
Debugger::log($rendererLibraryPath);
if (!PHPExcel_Settings::setPdfRenderer( $rendererName, $rendererLibraryPath )) { die( 'Please set the $rendererName and $rendererLibraryPath values' . PHP_EOL . ' as appropriate for your directory structure' . $rendererLibraryPath ); }
$objPHPExcel = new PHPExcel;
$objWriter = new PHPExcel_Writer_PDF($objPHPExcel);
//$objWriter->save("emptyPdfJustYet.pdf");
Tried their demo 21pdf.php to same results.
Can you help? Thanks a lot!!
When I print the error to log, I realize it is trying to load the dompdf_config.inc.php from an invalid location. See below.
C:\wamp\www\myapp\app\Vendor\dompdf\dompdf.php/dompdf_config.inc.php\n
Rather than altering the class files of PHPExcel, it's wise to change the configuration in your view. Ignoring the $rendererLibrary completely in the $rendererLibraryPath fixed my issue. I think the PHPExcel know how to pick dompdf.php file. Try below code let us know if it doesn't work.
And you are providing wrong render constant too, changed PDF_RENDERER_MPDF to PDF_RENDERER_DOMPDF.
$rendererName = PHPExcel_Settings::PDF_RENDERER_DOMPDF;
$rendererLibrary = 'dompdf.php';
$rendererLibraryPath = APP . 'Vendor' . DS . 'dompdf';
And for create writer object, I tried
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');
I have a library in my project.When I want to use this with this code:
require('../Plugin/Utils/DateTimeUtil.php');
it says no such file exists. my cakephp 1s 2.3 what should I do?
The Routing in cakephp is different from pure php.I had something like this.At first you should find the path Plugin folder with this code
$pluginPath = App::path('Plugin');
Then It returns an array which contains the plugin folder's path in 0 index.So you should the returned value like blow:
require($pluginPath[0] . 'Utils' . DS . 'DateTimeUtil.php');
You can use slash instead of DS. DS is DIRECTORY_SEPRATOR.
I am facing a curious situation. I am using CakePHP 2.0 (locally), XAMPP and I wanted to add a simple hit counter in my homepage so I added the following code (very very simple)
<?php
$filename = 'hitcount.txt';
$handle = fopen($filename, 'r');
$hits = trim(fgets($handle)) + 1;
fclose($handle);
$handle = fopen($filename, 'w');
fwrite($handle, $hits);
fclose($handle);
echo $hits;
There is a text file named hitcount.txt which contains the number of hits (everytime I visit the page it should increase the number of hits). It works. The problem appeared when I tried to access the hitcount.txt file. It was empty but the echo of $hits returned the exact result! I deleted the file and it still shows me the expected result! I used a different browser, the same. I deleted CakePHP's cache, no change. I used the same piece of code in another page and it did not complain with some error, returning the expected result.
How is it possible for Cakephp to "see" a file that does not exist? Has it anything to do with Apache?
You probably view the file at the wrong location as CakePHP's. My guess is CakePHP's referring to the file at app/webroot/hitcount.txt.
You might want to define a full path for hitcount.txt so you can be sure that you and CakePHP are both referring to the same location.
<?php
$filename = TMP.'hitcount.txt';
This would locate the file at `app/tmp/hitcount.txt'.
I have a project in CakePHP and I would like to know how to check if an image exists with the extension '.jpg' if not use the extension '.JPG', any help would be deeply appreciated.
bool file_exists ( string $filename )
Checks whether a file or directory exists. Returns TRUE if the file or directory specified by filename exists; FALSE otherwise.
http://php.net/manual/en/function.file-exists.php
$file = WWW_ROOT . 'img' . DS . 'uploads' . DS . 'file123.jpg';
my image path like app/webroot/img/upload/file123.jpg
WWW_ROOT define your webroot folder path and DS define '/'
$image='file123.jpg';
$file = WWW_ROOT . 'img' . DS . 'uploads' . DS . $image;
if conditions for file check
if(file_exists($file) && $image){
enter your code if file exists
}else{
file not exists
}