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
- Migrating
- 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 \setasign\SetaPDF2\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 \setasign\SetaPDF2\Core\Writer\WriterInterface
{
/**
* The response object
*
* @var MyResponse
*/
protected $_response;
/**
* The current position
*
* @var int
*/
protected $_pos = 0;
/**
* The current status
*
* @var int
*/
protected $_status = \setasign\SetaPDF2\Core\Writer\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 = \setasign\SetaPDF2\Core\Writer\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 = \setasign\SetaPDF2\Core\Writer\HttpWriter::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 \setasign\SetaPDF2\Core\Writer\EchoWriter
{
/**
* 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 = \setasign\SetaPDF2\Core\Writer\HttpWriter::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();
}
}
