Index
- Installation
- Getting Started
- Memory Usage
- Readers and Writers
- The Document Class
- Metadata
- Pages
- Canvas
- Page Layout and Mode
- Viewer Preferences
- Document Outline
- Page Labels
- Actions
- Destinations
- Annotations
- Embedded File Streams
- Colors and Color Spaces
- Page Formats and Boundaries
- Standard and Public Key Encryption
- Fonts and Encodings
- Corrupted Documents
- Reader Enabled Documents
- Refactor Old SetaPDF Code
- API Reference
Create a New Writer How to write new writer classes
Table of Contents
Introduction
The SetaPDF 2 core component already ships several writer classes for nearly all possible situations.
Anyhow, situations could occur where an individual implementation of a writer could be a smarter solution. For example a writer could directly write to a response object of a PHP framework which already handles the management of response headers.
Write Your Own Writer Class
Nearly all method names of the SetaPDF_Core_Writer_WriterInterface
are self-explanatory. There's a start()
-method which will be called when the writing process starts. A finish()
-method which will be called when the writing process ends, a getStatus()
-method which returnes status codes and a getPos()
-method to received the current byte offset position of the writer.
A simple writer, that forwards the output to a response object of type MyResponse
could look like this:
class MyWriter implements \SetaPDF_Core_Writer_Interface { /** * The response object * * @var MyResponse */ protected $_response; /** * The current position * * @var int */ protected $_pos = 0; /** * The current status * * @var int */ protected $_status = \SetaPDF_Core_Writer::INACTIVE; /** * Let's pass the response object to the writer * * @param MyResponse $response */ public function __construct(MyResponse $response) { $this->_response = $response; } /** * The output starts */ public function start() { // Let's clean the output buffer $this->_response->cleanBody(); // Set the status $this->_status = \SetaPDF_Core_Writer::ACTIVE; } /** * Write content to the response object * * @param string $s */ public function write($s) { // Add the new string to the response body $this->_response->appendBody($s); // Let's update the position $this->_pos += strlen($s); } /** * Implement the finish()-method */ public function finish() { $this->_status = \SetaPDF_Core_Writer::FINISHED; } /** * Implement the getStatus()-method * * @return int */ public function getStatus() { return $this->_status; } /** * Implement the getPos() method * * @return int */ public function getPos() { return $this->_pos; } }
The HTTP response headers, for example, have to be set in the controller then. Anyhow this also could be integrated into the writer class as well:
class MyWriterWithHeaders extends MyWriter { /** * The filename * * @var string */ protected $_filename = 'document.pdf'; /** * Let's pass the response object to the writer * * @param MyResponse $response * @param string $filename */ public function __construct(MyResponse $response, $filename = 'document.pdf') { parent::__construct($response); $this->_filename = $filename; } /** * Implement the finish()-method which also sets the headers */ public function finish() { $filename = SetaPDF_Core_Writer_Http::encodeFilenameForHttpHeader($this->_filename); // Let's add the headers $this->_response ->setHeader('Content-Type', 'application/download') ->setHeader('Content-Disposition', 'attachment; ' . $filename) ->setHeader('Content-Length', $this->getPos()) ->setHeader('Expires', '0') ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->setHeader('Pragma', 'public'); parent::finish(); } }
These examples are written from scratch. For sure an existing writer could be used and extended, which will result in less code:
class MyWriter extends \SetaPDF_Core_Writer_Echo { /** * The response object * * @var MyResponse */ protected $_response; /** * The filename * * @var string */ protected $_filename = 'document.pdf'; /** * Let's pass the response object to the writer * * @param MyResponse $response * @param string $filename */ public function __construct(MyResponse $response, $filename = 'document.pdf') { $this->_response = $response; $this->_filename = $filename; } /** * The output starts */ public function start() { // Let's clean the output buffer $this->_response->cleanBody(); parent::start(); } /** * Write content to the response object * * @param string $s */ public function write($s) { // Add the new string to the response body $this->_response->appendBody($s); // Let's update the position $this->_pos += strlen($s); } /** * Implement the finish()-method which also sets the headers */ public function finish() { $filename = SetaPDF_Core_Writer_Http::encodeFilenameForHttpHeader($this->_filename); // Let's add the headers $this->_response ->setHeader('Content-Type', 'application/download') ->setHeader('Content-Disposition', 'attachment; ' . $filename) ->setHeader('Content-Length', $this->getPos()) ->setHeader('Expires', '0') ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->setHeader('Pragma', 'public'); parent::finish(); } }