Dompdf converts fine on local but not on production server - laravel

I'm using Laravel 4 with dompdf package: https://github.com/barryvdh/laravel-dompdf
When I generate a report and it converts it to PDF on my local, everything is fine and displays well, but when I do the same exact thing on my production server, it displays random letters where there is either dynamic or static content.
Screenshot of local vs production:
http://s28.postimg.org/u5zk3pc19/report_diff.png
Here is the code that creates the PDF:
/**
* Create PDF
*
*/
public function createPdf( $reportData )
{
if( $this->validate() )
{
// Get Final Data Information
$btu_hp = static::getBtuHp( $reportData['booth_cfm'], $reportData['cure_temp_hp'], $reportData['outside_temp'] );
$btu_current = static::getBtuCurrent( $reportData['booth_cfm'], $reportData['bake_temp_current'], $reportData['outside_temp'] );
$reportData['energy_percentage_per_unit'] = static::getEnergyPercentagePerUnit( $btu_hp, $btu_current );
$reportData['energy_dollar_per_unit'] = static::getEnergyDollarPerUnit( $reportData['cost_per_therm'], $reportData['bake_time_current'], $reportData['cure_time_hp'], $btu_current, $btu_hp );
$reportData['time_savings_per_unit'] = static::getTimeSavingsPerUnit( $reportData['bake_time_current'], $reportData['cure_time_hp'] );
$reportData['time_savings_per_year'] = static::getTimeSavingsPerYear( $reportData['time_savings_per_unit'][0], $reportData['units_per_day'], $reportData['production_days'] );
$reportData['labor_dollar_per_year'] = static::getLaborDollarPerYear( $reportData['labor_rate'], $reportData['time_savings_per_year'][0] );
$reportData['energy_dollar_per_year'] = static::getEnergyDollarPerYear( $reportData['energy_dollar_per_unit'][0], $reportData['units_per_day'], $reportData['production_days'] );
$view = View::make('pages.report.hp-report.print', array('report' => $reportData));
if( ! $this->saveAsPdf($view, $this->generateFileName()) )
{
return false;
}
return true;
}
return false;
}
/**
* Save report as PDF
* #param html HTML of PDF
* #param fileName Name of File
*
*/
public function saveAsPdf( $html, $fileName = null )
{
if(is_null($fileName))
$fileName = $this->generateFileName();
$htmlPath = $this->reportDirectory.'/'.$fileName.'.html';
$pdfPath = $this->reportDirectory.'/'.$fileName.'.pdf';
file_put_contents( $htmlPath, $html );
// set recent PDF to name of PDF
$this->recentReportFile = $fileName . '.pdf';
return PDF::loadFile($htmlPath)->save($pdfPath);
}
/**
* Get most recent uploaded PDF
*
*/
public function getRecentPdf()
{
return $this->recentReportFile;
}
/**
* Generate file name for PDF
*
*/
public function generateFileName()
{
return Auth::user()->id . '_hp_' . str_random(10) . '_' . time();
}
Everything writes fine and it uses the right template and has the styling... Only the static content and dynamic content (values written out with PHP variables) display badly, although you can see some of the static content like Energy Savings and such prints fine.
Is there a reason this could be all jumbled up on the live server, but not local?
Here is the HTML for the view that is being grabbed (the HTML the php variables are injected into): http://pastebin.com/5bMR6G2s
And here is my config file for dompdf:
http://pastebin.com/Ld6MQckG

There are two possible causes for this:
Missing font(s) on the production server. Make sure you have the correct fonts installed on the production site.
Character encoding issues. I'm not sure which site (dev/live) the issue is on, but it may be that one is outputting UTF-8 and the other is not. You could try to sort this out by detecting the encoding on the input file on both dev and live by using mb_detect_encoding and see if they're different. If they are, then use mb_convert_encoding before converting to PDF.

Related

TYPO3 9.5 Extbase plugin cache implementation

I am trying to get a cache working in my plugin.
In ext_localconf.php
if (!is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['myextension'])) {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['myextension'] = [];}
if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['myextension']['frontend'])) {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['myextension']['frontend'] = 'TYPO3\\CMS\\Core\\Cache\\Frontend\\StringFrontend';}
if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['myextension']['options'])) {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['myextension']['options'] = ['defaultLifetime' => 0];}
if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['myextension']['groups'])) {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['myextension']['groups'] = ['pages'];}
In my controller action :
$cacheIdentifier = 'topic' . $topic->getUid();
$cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('myextension');
$result = unserialize($cache->get($cacheIdentifier));
if ($result !== false ) {
DebuggerUtility::var_dump($result);
} else {
$result = $this->postRepository->findByTopic($topic->getUid(), $page, $itemsPerPage);
$cache->set($cacheIdentifier, serialize($result), ['tag1', 'tag2']);
DebuggerUtility::var_dump($result);
}
The first time the page with the action gets loaded all is ok and the entry has been made in de database (cf_myextension and cf_myextension_tags}.
But the 2nd time the cache gets loaded and I get an error. Even DebuggerUtility::var_dump($result); does not work:
Call to a member function map() on null
in ../typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php line 96
*/
protected function initialize()
{
if (!is_array($this->queryResult)) {
$this->queryResult = $this->dataMapper->map($this->query->getType(), $this->persistenceManager->getObjectDataByQuery($this->query));
}
}
/**
A normal var_dump works and spits out the cache entry. What is the problem? Do I forget something? Can't a QueryResult together with some other variables not be stored as an array in the cache? I also tried VariableFrontend cache, which produced the same error.
The E-tools GUI application indents and pretty formats HTML, JavaScript, JSON and SQL. To install the e-tools snap package in all currently supported versions of Ubuntu open the terminal and type:
sudo snap install e-tools

Image returned by Symfony 4 not showing in React Native

I've written the following code to let my Symfony backend return an image:
/**
* #Route("/project/{id}/image", methods={"GET"}, name="get_project_image")
*/
public function getImage($id) {
$repository = $this->getDoctrine()->getRepository(Project::class);
$project = $repository->find($id);
$filePath = $this->getParameter('project_image_directory').$project->getImage();
return new BinaryFileResponse($filePath);
}
This image is also located in my public directory, so it's accessible through the following URL: http://192.168.1.128:8000/uploads/project/5f5d8575ebd98fa7fa970ad2d910314f.jpeg
Both URL's return an image when I open them in my browser, however, only the second shows up in my React Native app...

Return Image as http-response from Listener Symfony2

This listener sends me reports on all kinds of exceptions that occur on the website. Sometimes I get reports of images that have been deleted but are still consulted by search engines and others.
I want to do, instead of displaying an error message " 404 Not Found " return the correct image. To do this I created a database table that stores the old links and new links of the images that have been deleted, moved or changed its name.
then, this listener find in db the links to fallen and gets the new links of images . The goal is to return the image as http-response with header content-type as image.
My code is:
class ExceptionListener
{
private $service_container;
private $router;
function __construct(Container $service_container, $router){
$this->service_container = $service_container;
$this->router = $router;
}
public function onKernelException(GetResponseForExceptionEvent $event){
$exception = $event->getException();
$request = $this->service_container->get('request');
...
$document_root = $request->server->get('DOCUMENT_ROOT');
$filename = realpath($document_root . '/'. '/path/to/new_image.jpg');
$response = new \Symfony\Component\HttpFoundation\Response();
$response->headers->set('Content-type', 'image/jpeg');
$response->headers->set('Content-Disposition', 'inline; filename="' . basename($filename) . '";');
$response->headers->set('Content-length', filesize($filename));
$response->sendHeaders();
$response->setContent(file_get_contents($filename));
return $response;
...
}
}
The following error occurs:
In the browser you can see a small box , it is as if trying to show the image but the image source could not be obtained . But if the same code is testing on controller , its working properly and the image is displayed .
What can I do to return image from a listener ? thanks
There's few things wrong about the code snippet from your question.
Firstly, you should never use the request service. It's deprecated since Symfony 2.4 and was removed in Symfony 3.0. Use the request stack (request_stack) instead.
Secondly, do not send the response yourself, but let the framework do it. Symfony events system is designed for flexibility (see the docs). In your case it's enough to set the response on the event object.
Finally, you don't need the service container to access the request at all, as it's available on the event.
Moreover, instead of the standard Response class you can use the BinaryFileResponse. It's purpose is to serve files (have a look at the docs).
You can greatly simplify your listener:
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class ExceptionListener
{
private $router;
function __construct($router)
{
$this->router = $router;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
// request is avialable on the event
$request = $event->getRequest();
// ...
$file = 'path/to/file.txt';
$response = new BinaryFileResponse($file);
// ... set response parameters ...
// finally, set the response on your event
$event->setResponse($response);
}
}

Code Igniter + fine-uploader: IE9 and is_ajax_request command

After integrating fine-uploader script into a new code igniter installation, I have the following problem: IE 9 returns false when using the "if (!$this->input->is_ajax_request())" command.
class Welcome extends CI_Controller {
public function index()
{
$this->load->view('upload');
}
public function upload()
{
error_reporting(E_ALL | E_STRICT);
if (!$this->input->is_ajax_request())
{
die('No direct script access allowed');
}
$this->load->helper("qqFileUploader.class");
$uploader = new qqFileUploader('uploads');
// Specify the list of valid extensions, ex. array("jpeg", "xml", "bmp")
$uploader->allowedExtensions = array();
// Specify max file size in bytes.
$uploader->sizeLimit = 900 * 1024 * 1024; // 900 Megabytes
// Specify the input name set in the javascript.
$uploader->inputName = 'qqfile';
$uploader->prefix = 'test_';
// If you want to use resume feature for uploader, specify the folder to save parts.
$uploader->chunksFolder = 'chunks';
$result = $uploader->handleUpload('uploads');
$result['uploadName'] = $uploader->getUploadName();
header("Content-Type: text/plain");
echo json_encode($result);
}
}
Why?
This is completely expected. Fine Uploader does not use XHR to upload files in IE 9 and older (since this is not possible). Instead, we build a form and submit it, targeting an iframe.

Firefox Extension : Store Addon Data

I am building up a firefox extension which allows users to drag and drop things. Now if a user closes the application or reloads the page, I want to restore the last activity he did.
Example : User moves a box from point X to Y.
There can be many more boxes as well.
Now after page reload or application startup, if user puts the addon ON, I want the box's position to be Y. So for this purpose should I be using the firefox preference thing or is there any other better way of doing it.
I wrote a Firefox extension for accessing bookmarks from a site a friend of mine developed. I store the bookmarks data locally as JSON in a text file in the user's extension profile directory in case the bookmark service is down.
My function for saving bookmarks JSON is:
/**
* Stores bookmarks JSON to local persistence asynchronously.
*
* #param bookmarksJson The JSON to store
* #param fnSuccess The function to call upon success
* #param fnError The function to call upon error
*/
RyeboxChrome.saveBookmarkJson = function(bookmarksJson, fnSuccess, fnError) {
var cu = Components.utils;
cu.import("resource://gre/modules/NetUtil.jsm");
cu.import("resource://gre/modules/FileUtils.jsm");
var bookmarksJsonFile = RyeboxChrome.getOrCreateStorageDirectory();
bookmarksJsonFile.append("bookmarks.txt");
// You can also optionally pass a flags parameter here. It defaults to
// FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE;
var ostream = FileUtils.openSafeFileOutputStream(bookmarksJsonFile);
var converter = Components.classes["#mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var istream = converter.convertToInputStream(bookmarksJson);
NetUtil.asyncCopy(istream, ostream, function(status) {
if ( !Components.isSuccessCode(status) && typeof(fnError) === 'function' ) {
fnError();
} else if ( typeof(fnSuccess) === 'function' ) {
fnSuccess();
}
return;
});
};
The function for reading the data is:
/**
* Reads bookmarks JSON from local persistence asynchronously.
*
* #param fnSuccess Function to call when successful. The bookmarks JSON will
* be passed to this function.
*
* #param fnError Function to call upon failure.
*/
RyeboxChrome.getBookmarksJson = function(fnSuccess, fnError) {
Components.utils.import("resource://gre/modules/NetUtil.jsm");
var bookmarksJsonFile = RyeboxChrome.getOrCreateStorageDirectory();
bookmarksJsonFile.append("bookmarks.txt");
NetUtil.asyncFetch(bookmarksJsonFile, function(inputStream, status) {
if (!Components.isSuccessCode(status) && typeof(fnError) === 'function' ) {
fnError();
} else if ( typeof(fnSuccess) === 'function' ){
var data = NetUtil.readInputStreamToString(inputStream, inputStream.available());
fnSuccess(data);
}
});
};
Finally, my getOrCreateStorageDirectory function is:
/**
* Storage of data is done in a Ryebox directory within the user's profile
* directory.
*/
RyeboxChrome.getOrCreateStorageDirectory = function() {
var ci = Components.interfaces;
let directoryService = Components.classes["#mozilla.org/file/directory_service;1"].getService(ci.nsIProperties);
// Reference to the user's profile directory
let localDir = directoryService.get("ProfD", ci.nsIFile);
localDir.append("Ryebox");
if (!localDir.exists() || !localDir.isDirectory()) {
localDir.create(ci.nsIFile.DIRECTORY_TYPE, 0774);
}
return localDir;
};
It was suggested to me by Nickolay Ponomarev that using the following can be a good option:
Annotation Service
SQLite DB
Right now I am planning to use database for the usage.

Resources