TCPDF keep together function to keep content on 1 page (PDF generation) - php

I'm wondering if there's a keep together function for TCPDF. I have one for FPDF, but I can't get it to work in TCPDF.
Here's how I see it working within the PDF generation code:
// ... PDF code/stuff
// while not kept together
// add PDF stuff that should be kept together
// .. more PDF code/stuff
I'm thinking the function would return false if the a new page was added, roll back and then do the while loop again.
I do have the following working, but I'd rather it was in a function/method of TCPDF so it was more reusable:
$pdf->startTransaction();
$block_page = $pdf->getPage();
$print_block = 2; // max 2 tries
while ($print_block > 0) {
// do PDF stuff
if ($pdf->getPage() == $block_page) {
$print_block = 0;
} else {
// rollback
$pdf = $pdf->rollbackTransaction();
$pdf->AddPage();
$block_page = $pdf->getPage();
-- $print_block;
}
}
It would also be cool if it didn't depend on the built in transaction functionality so transactions can be used within the loop, since things like writeHTML() use transactions.

I wanted similar functionality and settled on using transactions. This on TCPDF version 5.9.125.
I inherited my own PDF class from TCPDF and added my own method:
public function writeHTMLTogether($html, $ln=true, $fill=false, $reseth=false, $cell=false, $align='') {
$cp = $this->getPage();
$this->startTransaction();
$this->writeHTML($html, $ln, $fill, $reseth, $cell, $align);
if ($this->getPage() > $cp) {
$this->rollbackTransaction(true);//true is very important
$this->AddPage();
$this->writeHTML($html, $ln, $fill, $reseth, $cell, $align);
} else {
$this->commitTransaction();
}
}
Seemed to work fine. Without the true in the rollback it breaks horribly, as writeHTML seems to store lots of properties somewhere.
May not need to create a local variable for current page ($cp) as I think it's stored. But hey.
If you're inheriting to write your own Header and Footer functions anyway, not much extra work.

Related

How to set or apply a function in wordpress for a specific screen width?

I'm struggling with applying the wordpress function for a specific screen width. Below is the given php function which I wish to apply for a particular screen width:
function add_specific_menu_atts( $atts, $item, $args ) {
$menu_items = array(4167, 4181, 4359, 4407, 4413, 4423, 4440);
if (in_array($item->ID, $menu_items)) {
$atts['data-toggle'] = 'dropdown';
}
return $atts;
}
add_filter( 'nav_menu_link_attributes', 'add_specific_menu_atts', 10, 3 );
I would really appreciate the much-needed help.
The main issue is that php does not have access to the screen width.
It would help if we knew what it is that you want to accomplish.
Also keep in mind that the user can resize the browser window after the page has loaded (or rotate the device) and php already finished it's job. Therefore, probably you are looking for a Javascript solution. This means, run the php function and set up some attributes or CSS classes and then have Javascript change things using those CSS classes.
I will assume that you use jQuery and have a menu in which you want certain elements to be hidden when the screen width is smaller than a threshold, say 800px.
Maybe this will help:
$(function() { // DOM is loaded
function resize() {
var bodyWidth = $('body').width();
if (bodyWidth < 800) {
$('.hide-on-mobile').hide();
} else {
$('.hide-on-mobile').show();
}
}
$(window).resize(function() {
resize();
});
resize(true); // initial call
});

DomPDF strange padding

I have an issue with dompdf where it shows me strange padding all the time that should not be there.
Above is the image where it is happening where my html itself i just a simple 1 tag with some text in it.
I initiate the library as:
class OmnPdf extends \Dompdf\Dompdf
{
public function __construct($options = null)
{
if($options == null){
$options = new \Dompdf\Options();
}
$options->setIsPhpEnabled(true);
$options->setIsHtml5ParserEnabled(true); // For combining multiple pdf outputs
$options->setIsFontSubsettingEnabled(true);
$options->setDefaultPaperSize('A4');
$options->setDebugCss(true);
$options->setDebugLayout(true);
$options->setDpi(72);
parent::__construct($options);
}
}
What i am expecting is that the text will be alligned according the outer page (see red line).
Thanks,
Pim
Are you loading a custom font? Because I'm pretty sure this is causing your issue.

PHPExcel: print page margins and print auto fit seems not working

I'm calling these 3 functions one after other in this exact order
public function setPrintFitToWidth()
{
$this->sheet->getPageSetup()->setFitToWidth(1);
}
public function setPrintArea($cell_area)
{
$this->sheet->getPageSetup()->setPrintArea($cell_area);
}
public function setPrintMargins($top, $right, $bottom, $left)
{
$this->sheet->getPageMargins()->setTop($top);
$this->sheet->getPageMargins()->setRight($right);
$this->sheet->getPageMargins()->setLeft($left);
$this->sheet->getPageMargins()->setBottom($bottom);
}
The problem is that, opening resulting Excel file, I've page margin set to 'custom' but, in fact, set to different values instead of margin I passed to my function. In fact I called with argument (1,0.5,0.5,1) but I got, in the same orders, 2, 0.8, 0.8, 2. It's really strange ...
Also: I cannot get working setFittoWidth(1); I expect to see adapted for all column in one page, but Excel tell me It's setup on adapt sheet on a page.
What am I doing wrong?
Resolved:
changed
public function setPrintFitToWidth()
{
$this->sheet->getPageSetup()->setFitToWidth(1);
}
to
public function setPrintFitToWidth()
{
$this->sheet->getPageSetup()->setFitToWidth(1);
$this->sheet->getPageSetup()->setFitToHeight(0);
}
About the margins: I tried with zero and margin are respected, so I concluded than PHPExcel unit are in someway 'scaled down'... So, after some 'try' and 'redo', I found the values that generate the correct magins

Making Greyscale image in Silverstripe

I'd like to be able to return an image in Black&white in a controller, so I can use it in a template. On this page I found that the GD class has a greyscale method. Unfortunately I don't understand the GD class and how I can use it. I tried doing
$final = $image->getFormattedImage('greyscale',36,36,36);
But that didn't work. It does return an image object with a new URL but the image does not exist.
Can anyone explain to me how to make an imageobject into a greyscale image in a Silverstripe page Controller?
Well I had a go myself and this is what I came up with:
_config.php
Object::add_extension('Image', 'Greyscaled');
UPDATE: as of SilverStripe 3.1, you should use the config system instead of _config.php. Put the following in your mysite/_config/config.yml (Don't forget to ?flush=1 to reload the config cache after adding it):
Image:
extensions:
- 'Greyscaled'
Greyscaled.php
<?php
class Greyscaled extends DataExtension {
//This allows the template to pick up "GreyscaleImage" property, it requests a copy of the image from the cache or if it doesn't exist, generates a new one
public function GreyscaleImage($RGB = '76 147 29') {
return $this->owner->getFormattedImage('GreyscaleImage', $RGB);
}
//This is called internally by "generateFormattedImage" when the item is not already cached
public function generateGreyscaleImage(GD $gd, $RGB) {
$Vars = explode(' ', $RGB);
return $gd->greyscale($Vars[0], $Vars[1], $Vars[2]);
}
}
UPDATE2: With newer Versions of 3.1 ?? you can pass in more than 2 parameters and GD has been renamed to Image_Backend. This way you do not have spaces between the RGB-values in the image-name. Be aware $gd->greyscale needs a lot of juice - so you probable better downsize first and GreyscaleImage afterwards.
UPDATE3: Since this answer got some votes recently I assume people still using it, but I think in 2017 CSS filters are in many cases a better choice. Prefixed you'll have close to 90% coverage.
css-filters on caniuse.com
<?php
class Greyscaled extends DataExtension {
public function GreyscaleImage($R = '76', $G = '147', $B = '29') {
return $this->owner->getFormattedImage('GreyscaleImage', $R, $G, $B);
}
public function generateGreyscaleImage(Image_Backend $gd, $R, $G, $B) {
return $gd->greyscale($R, $G, $B);
}
}
and in the template:
<img src="$Images.GreyscaleImage.CroppedImage(1000,400).URL" alt="$Images.Title" />
Silverstripe 3.1 Image API
There is a module for this. Sorry but it's not on packagist just yet.
https://github.com/NightJar/ssrigging-greyscaleimages

PHP: passing array elements into class function in fpdf

Working on a project and need to generate pdf of the product details using FPDF. The product details are passed into an array and I need the following to get each of the variable elements in the array '$prod_details' into the functions within the class 'PDF' as shown below:
Examples of how I tried passing the variable array elements:
$this->Cell(30,8,$prod_data['prod_name'],0,0,'C');
$this->Cell(30,10,$prod_data['company_name']);
$this->Cell(20,8,$prod_data['prod_cost'],0,0,'C');
I have tried running this script but I keep getting an error message 'Cannot access empty property'...
find the codes below
<?php
#include_once("includes/db.php");
require('fpdf/fpdf.php');
#include_once("includes/class_product_info.php");
$obj = new allProducts();
$prod_data = array();
if(isset($_GET['c_id'])){
$prod_data = $obj->getProdDetails($_GET['c_id']);
class PDF extends FPDF
{
public $prod_data;
public function createData($input){
$this->prod_data = $input;
}
function Header()
{
// Logo
$this->Image('big_logo.png',10,6,30);
// Arial bold 15
$this->SetFont('Arial','B',20);
// Move to the right
$this->Cell(40);
// Title
$this->Cell(30,10,$this->prod_data['company_name']);
// Draw an header line
$this->Line(10,26,200,26);
// Line break
$this->Ln(20);
}
function Footer()
{
// Position at 1.5 cm from bottom
$this->SetY(-15);
// Begin with regular font
$this->SetFont('Arial','',9);
// Then put a blue underlined link
//$this->SetTextColor(0,0,255);
$this->SetFont('','U');
$this->Write(10,$this->prod_data['company_name'],'http://www.skills.com');
// Arial italic 8
$this->SetFont('Arial','I',9);
// Page number
$this->Cell(0,10,'Page '.$this->PageNo().' ',0,0,'R');
}
function prodDetailTop()
{
// Course title cell
$this->Cell('',10,'',0,0,'C');
$this->Ln();
/* Build cells for the first row */
$this->SetFont('Arial','',10);
$this->SetY(40);
// First Row
$this->Cell(35,8,'Product Name : ',0,0,'L');
$this->Cell(30,8,$this->prod_data['prod_name'],0,0,'C');
$this->SetX(150);
$this->Cell(25,8,'Product Cost : ',0,0,'L');
$this->Cell(20,8,$this->prod_data['prod_cost'],0,0,'C');
$this->Ln();
// Second Row
$this->Cell(35,8,'Discount : ',0,0,'L');
$this->Cell(30,8,$this->prod_data['disc_amt'],0,0,'L');
$this->SetX(150);
$this->Cell(25,8,'No Purchased : ',0,0,'L');
$this->Cell(20,8,$this->prod_data['items_count'].' product(s)',0,0,'L');
$this->Ln();
}
function prodDetailBtm()
{
$this->SetY(80);
$this->Write(10,$this->prod_data['prod_desc']);
}
function generatePageData()
{
$this->AddPage();
$this->prodDetailTop();
$this->prodDetailBtm();
}
}
$pdf = new PDF();
$pdf->createData($prod_data);
//$pdf->Header();
$pdf->generatePageData();
$pdf->Output();
}
else {
?>
<script language="javascript">
window.location = "prod_invoice_err.php";
</script>
<?php
}
?>
Hope to get some help.
Your question is a little vague. It would be helpful it you asked specifically what you're trying to accomplish.
But the first thing I see is that your subclass of the fpdf class, you don't need to write functions to do each and everything you want to do with the pdf. You only need to extend the parts of the class you are overriding (or extending), like header and footer.
So extend it, manipulate header and footer, then close the class. Create your $pdf instance of your new fpdf class, then manipulate that object with your data. You don't need to 'pass in' that data at all.
for instance:
$pdf->Ln(10);
$pdf->Cell($w,9,$title,1,1,'C',true); //from fpdf tutorial
Or, if that doesn't accomplish what you want (although I can't see why it wouldn't, I've done this lots of times), you can always override the constructor. Pass in an array (or event a custom object that you create), and store that in a private variable.

Categories