Subscribe to PHP Freaks RSS

UFPDF: Quick and dirty fix for page numbering

Print
by MichaƂ Jarosz on Nov 11, 2009 10:27:59 AM - 7,974 views

UFPDF is a Unicode/UTF-8 extension for FPDF by Steven Wittens. It is quite outdated right now, but if for some reasons you're stuck with it, you might not like the fact, that one quite important function is broken.

In FPDF you can use AliasNbPages method, to specify a 'total pages' alias - a short string that will be replaced with total number of pages in document when PDF is generated. So if you for example do:

$this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C');   //{nb} is a default AliasNbPages

and your document has 12 pages, {nb} will be replaced with 12 on each page.

Unfortunately in UFPDF this does not work. UFPDF is replacing and adding some UTF-8 enabled methods to core FPDF class, which on its side does most of the generating PDF work. (BTW: you can safely replace fpdf.php that is in UFPDF download, with the newest version from FPDF site without breaking anything) Substituting AliasNbPages for number of pages is also handled by FPDF by means of simple str_replace. That's where it fails:

function _putpages()
{
	$nb=$this->page;
	if(!empty($this->AliasNbPages))
	{
		//Replace number of pages
		for($n=1;$n<=$nb;$n++)
			$this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]);
	}
...
}

All content generated by UFPDF is already UTF-8/Unicode encoded at this moment, so str_replace just can't find the alias and replace it. I've spend some time trying to find out a nice fix for this using mb_string or other encoding conversion functions, but ultimately I've come up with this:

function _putpages()
{
	$nb=$this->page;
	if(!empty($this->AliasNbPages))
	{
		//Replace number of pages
		
		$nb = (string)$nb;
		$nbs = '';
		for($i = 0;$i < strlen($nb); $i++) {
			$nbs .= "\0".$nb[$i];
		}
		
		$alias = $this->AliasNbPages;
		$aliass = '';
		for($i = 0;$i < strlen($alias); $i++) {
			$aliass .= "\0".$alias[$i];
		}
		
		for($n=1;$n<=$nb;$n++)
			$this->pages[$n]=str_replace($aliass,$nbs,$this->pages[$n]);
	}
...
}

What it does is it adds additional \0 character (essentially a byte with value 0) in front of each character in AliasNbPages. It does the same to the number of pages string. Then it just replaces one with the other.

It's ugly as hell, but it works. One limitation is, you should only use characters from ASCII set to define AliasNbPages (default {nb} works well).

Comments

No comments have been posted.

Add Comment

Login or register to post a comment.