Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add decorator infrastructure for plugins #1519

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

rudiedirkx
Copy link
Contributor

@rudiedirkx rudiedirkx commented Aug 21, 2017

I want to make a few decorators for Dompdf tweaks I often use. To make a decorator, I need a simple interface that Dompdf already implements, so my decorators can implement the same interface. With decorators, you make make very useful Dompdf plugins that interact at any (public) moment in the Dompdf flow.

I've made 2 (no stealing!):

  • Pageable - parses multiple <body> in input HTML to make multiple PDF and then merge them into one
  • Processable - pre-processes input HTML to change simple expressive HTML intro page scripts etc

This PR doesn't actually include the plugins, but it allows for them by creating the infrastructure. All of this is doable without this PR, but not as pretty. I've only included the methods I need, not all public methods, because there are many. Maybe a few more would be more useful for other scenario's, but I haven't missed any. It's fully backward compatible too.

Demo decorators and current hacky infrastructure at rudiedirkx/dompdf-demo

Very simple example to make all input documents UTF-8, because typing is such a hassle:

// Plugin
class Utf8Dompdf extends DompdfDecorator // implements DompdfInterface
{
  public function loadHtml($html)
  {
    $html = str_replace('<head>', <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />', $html);
    $this->pdf->loadHtml($html);
  }
}

// Implementation
$options = new Options();
$dompdf = new Utf8Dompdf(new Dompdf($options));

This simple example could of course be much easier by extending Dompdf. The benefit from decorators comes from combining them, and adding config and logic that doesn't belong in Dompdf itself..

@simonberger
Copy link
Member

You may not name the method clone

@rudiedirkx
Copy link
Contributor Author

How about copy() ?

It might be nice to just use the same Dompdf object twice, but I couldn't get that to work.

@rudiedirkx
Copy link
Contributor Author

(Btw, tests would be much faster with a composer.lock.)

@rudiedirkx
Copy link
Contributor Author

Did you see my cool PagerProcessor?

return implode("\n", [
	'<script type="text/php">$GLOBALS["' . $name . '"] = $pdf->open_object();</script>',
	$content,
	'<script type="text/php">',
	'$pdf->close_object();',
	'$pdf->page_script(\'',
	'	if ((!' . $firstPage . ' || $PAGE_NUM >= ' . $firstPage . ') && (!' . $lastPage . ' || $PAGE_NUM <= ' . $lastPage . ')) {',
	'		$nobj = $pdf->open_object(); $pdf->close_object();',
	'		$pdf->get_cpdf()->objects[$nobj] = $pdf->get_cpdf()->objects[ $GLOBALS["' . $name . '"] ];',
	'		$pdf->get_cpdf()->objects[$nobj]["c"] = strtr($pdf->get_cpdf()->objects[$nobj]["c"], [',
	'			"%n" => $PAGE_NUM,',
	'			"%t" => $PAGE_COUNT,',
	'		]);',
	'		$pdf->add_object($nobj);',
	'	}',
	'\');',
	'</script>',
]);

PHP writing HTML writing PHP with a string of PHP with variables. Waaat. It's not pretty, but it makes the input HTML much prettier:

<div class="pager">
	<dompdf-pager pages="2-">%n / %t</dompdf-pager>
</div>

So that's what this PR can do, indirectly.

@bsweeney
Copy link
Member

It's an interesting concept. We'll take a closer look as we have time.

@rudiedirkx
Copy link
Contributor Author

rudiedirkx commented Aug 27, 2017

Excellent. There are more usages at rudiedirkx/dompdf-demo

@rudiedirkx
Copy link
Contributor Author

Did ya did ya? I'd very much like to change my patched dompdf to a stable release.

I'm sure many users would be happy to have some template sugar like <dompdf-pager>. These <script>s are tricky.

@bsweeney
Copy link
Member

bsweeney commented Nov 4, 2017

I'm slammed these days so I'll only be working on bug fixes for the next release. Will keep you updated on progress with this enhancement.

@bsweeney bsweeney changed the base branch from develop to master November 8, 2021 19:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants