Refactor writers and readers

- Create Writer abstract class
- Inherit writers class from Writer
- Inherit ODText\WriterPart from Word2007\WriterPart
- Rename AbstractReader > Reader
This commit is contained in:
Ivan Lanin 2014-03-30 16:31:01 +07:00
parent 0e2f476cc2
commit 4127860f1e
23 changed files with 310 additions and 501 deletions

View File

@ -21,6 +21,8 @@ This is the changelog between releases of PHPWord. Releases are listed in revers
### Miscellaneous ### Miscellaneous
- Documentation: Simplify page level docblock - @ivanlanin GH-179 - Documentation: Simplify page level docblock - @ivanlanin GH-179
- Writer: Refactor writer classes and make a new Writer abstract class - @ivanlanin GH-160
- Reader: Rename AbstractReader > Reader - @ivanlanin
## 0.9.1 - 27 Mar 2014 ## 0.9.1 - 27 Mar 2014

View File

@ -16,7 +16,7 @@ use PhpOffice\PhpWord\Exceptions\Exception;
* *
* @codeCoverageIgnore Abstract class * @codeCoverageIgnore Abstract class
*/ */
abstract class AbstractReader implements IReader abstract class Reader implements IReader
{ {
/** /**
* Read data only? * Read data only?

View File

@ -16,7 +16,7 @@ use PhpOffice\PhpWord\Exceptions\Exception;
/** /**
* Reader for Word2007 * Reader for Word2007
*/ */
class Word2007 extends AbstractReader implements IReader class Word2007 extends Reader implements IReader
{ {
/** /**
* Can the current IReader read the file? * Can the current IReader read the file?

View File

@ -21,42 +21,14 @@ use PhpOffice\PhpWord\Writer\ODText\Styles;
/** /**
* ODText writer * ODText writer
*/ */
class ODText implements IWriter class ODText extends Writer implements IWriter
{ {
/**
* PHPWord object
*
* @var \PhpOffice\PhpWord\PhpWord
*/
private $_document;
/**
* Individual writers
*
* @var \PhpOffice\PhpWord\Writer\ODText\WriterPart[]
*/
private $_writerParts;
/** /**
* Private unique PHPWord_Worksheet_BaseDrawing HashTable * Private unique PHPWord_Worksheet_BaseDrawing HashTable
* *
* @var \PhpOffice\PhpWord\HashTable * @var \PhpOffice\PhpWord\HashTable
*/ */
private $_drawingHashTable; private $drawingHashTable;
/**
* Use disk caching where possible?
*
* @var boolean
*/
private $_useDiskCaching = false;
/**
* Disk caching directory
*
* @var string
*/
private $_diskCachingDirectory;
/** /**
* Create new ODText writer * Create new ODText writer
@ -67,24 +39,18 @@ class ODText implements IWriter
// Assign PhpWord // Assign PhpWord
$this->setPhpWord($phpWord); $this->setPhpWord($phpWord);
// Set up disk caching location // Set writer parts
$this->_diskCachingDirectory = './'; $this->writerParts['content'] = new Content();
$this->writerParts['manifest'] = new Manifest();
// Initialise writer parts $this->writerParts['meta'] = new Meta();
$this->_writerParts['content'] = new Content(); $this->writerParts['mimetype'] = new Mimetype();
$this->_writerParts['manifest'] = new Manifest(); $this->writerParts['styles'] = new Styles();
$this->_writerParts['meta'] = new Meta(); foreach ($this->writerParts as $writer) {
$this->_writerParts['mimetype'] = new Mimetype();
$this->_writerParts['styles'] = new Styles();
// Assign parent IWriter
foreach ($this->_writerParts as $writer) {
$writer->setParentWriter($this); $writer->setParentWriter($this);
} }
// Set HashTable variables // Set HashTable variables
$this->_drawingHashTable = new HashTable(); $this->drawingHashTable = new HashTable();
} }
/** /**
@ -95,17 +61,8 @@ class ODText implements IWriter
*/ */
public function save($pFilename = null) public function save($pFilename = null)
{ {
if (!is_null($this->_document)) { if (!is_null($this->phpWord)) {
// If $pFilename is php://output or php://stdout, make it a temporary file... $pFilename = $this->getTempFile($pFilename);
$originalFilename = $pFilename;
if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
$pFilename = @tempnam(sys_get_temp_dir(), 'phpword_');
if ($pFilename == '') {
$pFilename = $originalFilename;
}
}
// Create drawing dictionary
// Create new ZIP file and open it for writing // Create new ZIP file and open it for writing
$objZip = new \ZipArchive(); $objZip = new \ZipArchive();
@ -119,19 +76,19 @@ class ODText implements IWriter
// Add mimetype to ZIP file // Add mimetype to ZIP file
//@todo Not in \ZipArchive::CM_STORE mode //@todo Not in \ZipArchive::CM_STORE mode
$objZip->addFromString('mimetype', $this->getWriterPart('mimetype')->writeMimetype($this->_document)); $objZip->addFromString('mimetype', $this->getWriterPart('mimetype')->writeMimetype($this->phpWord));
// Add content.xml to ZIP file // Add content.xml to ZIP file
$objZip->addFromString('content.xml', $this->getWriterPart('content')->writeContent($this->_document)); $objZip->addFromString('content.xml', $this->getWriterPart('content')->writeContent($this->phpWord));
// Add meta.xml to ZIP file // Add meta.xml to ZIP file
$objZip->addFromString('meta.xml', $this->getWriterPart('meta')->writeMeta($this->_document)); $objZip->addFromString('meta.xml', $this->getWriterPart('meta')->writeMeta($this->phpWord));
// Add styles.xml to ZIP file // Add styles.xml to ZIP file
$objZip->addFromString('styles.xml', $this->getWriterPart('styles')->writeStyles($this->_document)); $objZip->addFromString('styles.xml', $this->getWriterPart('styles')->writeStyles($this->phpWord));
// Add META-INF/manifest.xml // Add META-INF/manifest.xml
$objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('manifest')->writeManifest($this->_document)); $objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('manifest')->writeManifest($this->phpWord));
// Add media. Has not used yet. Legacy from PHPExcel. // Add media. Has not used yet. Legacy from PHPExcel.
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
@ -173,46 +130,12 @@ class ODText implements IWriter
throw new Exception("Could not close zip file $pFilename."); throw new Exception("Could not close zip file $pFilename.");
} }
// If a temporary file was used, copy it to the correct file stream $this->cleanupTempFile();
if ($originalFilename != $pFilename) {
if (copy($pFilename, $originalFilename) === false) {
throw new Exception("Could not copy temporary zip file $pFilename to $originalFilename.");
}
@unlink($pFilename);
}
} else { } else {
throw new Exception("PhpWord object unassigned."); throw new Exception("PhpWord object unassigned.");
} }
} }
/**
* Get PhpWord object
*
* @return \PhpOffice\PhpWord\PhpWord
* @throws \PhpOffice\PhpWord\Exceptions\Exception
*/
public function getPhpWord()
{
if (!is_null($this->_document)) {
return $this->_document;
} else {
throw new Exception("No PhpWord assigned.");
}
}
/**
* Set PhpWord object
*
* @param \PhpOffice\PhpWord\PhpWord $phpWord
* @return \PhpOffice\PhpWord\Writer\ODText
*/
public function setPhpWord(PhpWord $phpWord = null)
{
$this->_document = $phpWord;
return $this;
}
/** /**
* Get PHPWord_Worksheet_BaseDrawing HashTable * Get PHPWord_Worksheet_BaseDrawing HashTable
* *
@ -220,64 +143,6 @@ class ODText implements IWriter
*/ */
public function getDrawingHashTable() public function getDrawingHashTable()
{ {
return $this->_drawingHashTable; return $this->drawingHashTable;
}
/**
* Get writer part
*
* @param string $pPartName Writer part name
* @return \PhpOffice\PhpWord\Writer\ODText\WriterPart
*/
public function getWriterPart($pPartName = '')
{
if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) {
return $this->_writerParts[strtolower($pPartName)];
} else {
return null;
}
}
/**
* Get use disk caching where possible?
*
* @return boolean
*/
public function getUseDiskCaching()
{
return $this->_useDiskCaching;
}
/**
* Set use disk caching where possible?
*
* @param boolean $pValue
* @param string $pDirectory Disk caching directory
* @throws \PhpOffice\PhpWord\Exceptions\Exception Exception when directory does not exist
* @return \PhpOffice\PhpWord\Writer\ODText
*/
public function setUseDiskCaching($pValue = false, $pDirectory = null)
{
$this->_useDiskCaching = $pValue;
if (!is_null($pDirectory)) {
if (is_dir($pDirectory)) {
$this->_diskCachingDirectory = $pDirectory;
} else {
throw new Exception("Directory does not exist: $pDirectory");
}
}
return $this;
}
/**
* Get disk caching directory
*
* @return string
*/
public function getDiskCachingDirectory()
{
return $this->_diskCachingDirectory;
} }
} }

View File

@ -41,12 +41,7 @@ class Content extends WriterPart
public function writeContent(PhpWord $phpWord = null) public function writeContent(PhpWord $phpWord = null)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8'); $xmlWriter->startDocument('1.0', 'UTF-8');

View File

@ -27,12 +27,7 @@ class Manifest extends WriterPart
public function writeManifest(PhpWord $phpWord = null) public function writeManifest(PhpWord $phpWord = null)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8'); $xmlWriter->startDocument('1.0', 'UTF-8');

View File

@ -26,12 +26,7 @@ class Meta extends WriterPart
public function writeMeta(PhpWord $phpWord = null) public function writeMeta(PhpWord $phpWord = null)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8'); $xmlWriter->startDocument('1.0', 'UTF-8');

View File

@ -30,12 +30,7 @@ class Styles extends WriterPart
public function writeStyles(PhpWord $phpWord = null) public function writeStyles(PhpWord $phpWord = null)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8'); $xmlWriter->startDocument('1.0', 'UTF-8');

View File

@ -9,43 +9,9 @@
namespace PhpOffice\PhpWord\Writer\ODText; namespace PhpOffice\PhpWord\Writer\ODText;
use PhpOffice\PhpWord\Exceptions\Exception;
use PhpOffice\PhpWord\Writer\IWriter;
/** /**
* ODText writer part abstract * ODText writer part abstract
*/ */
abstract class WriterPart abstract class WriterPart extends \PhpOffice\PhpWord\Writer\Word2007\WriterPart
{ {
/**
* Parent IWriter object
*
* @var \PhpOffice\PhpWord\Writer\IWriter
*/
private $_parentWriter;
/**
* Set parent IWriter object
*
* @param \PhpOffice\PhpWord\Writer\IWriter $pWriter
*/
public function setParentWriter(IWriter $pWriter = null)
{
$this->_parentWriter = $pWriter;
}
/**
* Get parent IWriter object
*
* @return \PhpOffice\PhpWord\Writer\IWriter
* @throws \PhpOffice\PhpWord\Exceptions\Exception
*/
public function getParentWriter()
{
if (!is_null($this->_parentWriter)) {
return $this->_parentWriter;
} else {
throw new Exception("No parent IWriter assigned.");
}
}
} }

View File

@ -31,42 +31,35 @@ use PhpOffice\PhpWord\TOC;
/** /**
* RTF writer * RTF writer
*/ */
class RTF implements IWriter class RTF extends Writer implements IWriter
{ {
/**
* Private PhpWord
*
* @var \PhpOffice\PhpWord\PhpWord
*/
private $_document;
/** /**
* Private unique PHPWord_Worksheet_BaseDrawing HashTable * Private unique PHPWord_Worksheet_BaseDrawing HashTable
* *
* @var \PhpOffice\PhpWord\HashTable * @var \PhpOffice\PhpWord\HashTable
*/ */
private $_drawingHashTable; private $drawingHashTable;
/** /**
* Color register * Color register
* *
* @var array * @var array
*/ */
private $_colorTable; private $colorTable;
/** /**
* Font register * Font register
* *
* @var array * @var array
*/ */
private $_fontTable; private $fontTable;
/** /**
* Last paragraph style * Last paragraph style
* *
* @var mixed * @var mixed
*/ */
private $_lastParagraphStyle; private $lastParagraphStyle;
/** /**
* Create new RTF writer * Create new RTF writer
@ -78,7 +71,7 @@ class RTF implements IWriter
$this->setPhpWord($phpWord); $this->setPhpWord($phpWord);
// Set HashTable variables // Set HashTable variables
$this->_drawingHashTable = new HashTable(); $this->drawingHashTable = new HashTable();
} }
/** /**
@ -89,60 +82,19 @@ class RTF implements IWriter
*/ */
public function save($pFilename = null) public function save($pFilename = null)
{ {
if (!is_null($this->_document)) { if (!is_null($this->phpWord)) {
// If $pFilename is php://output or php://stdout, make it a temporary file... $pFilename = $this->getTempFile($pFilename);
$originalFilename = $pFilename;
if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
$pFilename = @tempnam(sys_get_temp_dir(), 'phpword_');
if ($pFilename == '') {
$pFilename = $originalFilename;
}
}
$hFile = fopen($pFilename, 'w') or die("can't open file"); $hFile = fopen($pFilename, 'w') or die("can't open file");
fwrite($hFile, $this->getData()); fwrite($hFile, $this->getData());
fclose($hFile); fclose($hFile);
// If a temporary file was used, copy it to the correct file stream $this->cleanupTempFile();
if ($originalFilename != $pFilename) {
if (copy($pFilename, $originalFilename) === false) {
throw new Exception("Could not copy temporary zip file $pFilename to $originalFilename.");
}
@unlink($pFilename);
}
} else { } else {
throw new Exception("PhpWord object unassigned."); throw new Exception("PhpWord object unassigned.");
} }
} }
/**
* Get PhpWord object
*
* @return \PhpOffice\PhpWord\PhpWord
* @throws \PhpOffice\PhpWord\Exceptions\Exception
*/
public function getPhpWord()
{
if (!is_null($this->_document)) {
return $this->_document;
} else {
throw new Exception("No PhpWord assigned.");
}
}
/**
* Set PhpWord object
*
* @param \PhpOffice\PhpWord\PhpWord $phpWord
* @return \PhpOffice\PhpWord\Writer\RTF
*/
public function setPhpWord(PhpWord $phpWord = null)
{
$this->_document = $phpWord;
return $this;
}
/** /**
* Get PHPWord_Worksheet_BaseDrawing HashTable * Get PHPWord_Worksheet_BaseDrawing HashTable
* *
@ -150,7 +102,7 @@ class RTF implements IWriter
*/ */
public function getDrawingHashTable() public function getDrawingHashTable()
{ {
return $this->_drawingHashTable; return $this->drawingHashTable;
} }
/** /**
@ -160,9 +112,9 @@ class RTF implements IWriter
*/ */
private function getData() private function getData()
{ {
// PhpWord object : $this->_document // PhpWord object : $this->phpWord
$this->_fontTable = $this->getDataFont(); $this->fontTable = $this->getDataFont();
$this->_colorTable = $this->getDataColor(); $this->colorTable = $this->getDataColor();
$sRTFContent = '{\rtf1'; $sRTFContent = '{\rtf1';
// Set the default character set // Set the default character set
@ -174,13 +126,13 @@ class RTF implements IWriter
$sRTFContent .= \PHP_EOL; $sRTFContent .= \PHP_EOL;
// Set the font tbl group // Set the font tbl group
$sRTFContent .= '{\fonttbl'; $sRTFContent .= '{\fonttbl';
foreach ($this->_fontTable as $idx => $font) { foreach ($this->fontTable as $idx => $font) {
$sRTFContent .= '{\f' . $idx . '\fnil\fcharset0 ' . $font . ';}'; $sRTFContent .= '{\f' . $idx . '\fnil\fcharset0 ' . $font . ';}';
} }
$sRTFContent .= '}' . \PHP_EOL; $sRTFContent .= '}' . \PHP_EOL;
// Set the color tbl group // Set the color tbl group
$sRTFContent .= '{\colortbl '; $sRTFContent .= '{\colortbl ';
foreach ($this->_colorTable as $idx => $color) { foreach ($this->colorTable as $idx => $color) {
$arrColor = Drawing::htmlToRGB($color); $arrColor = Drawing::htmlToRGB($color);
$sRTFContent .= ';\red' . $arrColor[0] . '\green' . $arrColor[1] . '\blue' . $arrColor[2] . ''; $sRTFContent .= ';\red' . $arrColor[0] . '\green' . $arrColor[1] . '\blue' . $arrColor[2] . '';
} }
@ -218,12 +170,12 @@ class RTF implements IWriter
*/ */
private function getDataFont() private function getDataFont()
{ {
$phpWord = $this->_document; $phpWord = $this->phpWord;
$arrFonts = array(); $arrFonts = array();
// Default font : PhpWord::DEFAULT_FONT_NAME // Default font : PhpWord::DEFAULT_FONT_NAME
$arrFonts[] = PhpWord::DEFAULT_FONT_NAME; $arrFonts[] = PhpWord::DEFAULT_FONT_NAME;
// PhpWord object : $this->_document // PhpWord object : $this->phpWord
// Browse styles // Browse styles
$styles = Style::getStyles(); $styles = Style::getStyles();
@ -273,10 +225,10 @@ class RTF implements IWriter
*/ */
private function getDataColor() private function getDataColor()
{ {
$phpWord = $this->_document; $phpWord = $this->phpWord;
$arrColors = array(); $arrColors = array();
// PhpWord object : $this->_document // PhpWord object : $this->phpWord
// Browse styles // Browse styles
$styles = Style::getStyles(); $styles = Style::getStyles();
@ -334,7 +286,7 @@ class RTF implements IWriter
*/ */
private function getDataContent() private function getDataContent()
{ {
$phpWord = $this->_document; $phpWord = $this->phpWord;
$sRTFBody = ''; $sRTFBody = '';
$_sections = $phpWord->getSections(); $_sections = $phpWord->getSections();
@ -400,7 +352,7 @@ class RTF implements IWriter
} }
if ($styleParagraph && !$withoutP) { if ($styleParagraph && !$withoutP) {
if ($this->_lastParagraphStyle != $text->getParagraphStyle()) { if ($this->lastParagraphStyle != $text->getParagraphStyle()) {
$sRTFText .= '\pard\nowidctlpar'; $sRTFText .= '\pard\nowidctlpar';
if ($styleParagraph->getSpaceAfter() != null) { if ($styleParagraph->getSpaceAfter() != null) {
$sRTFText .= '\sa' . $styleParagraph->getSpaceAfter(); $sRTFText .= '\sa' . $styleParagraph->getSpaceAfter();
@ -410,17 +362,17 @@ class RTF implements IWriter
$sRTFText .= '\qc'; $sRTFText .= '\qc';
} }
} }
$this->_lastParagraphStyle = $text->getParagraphStyle(); $this->lastParagraphStyle = $text->getParagraphStyle();
} else { } else {
$this->_lastParagraphStyle = ''; $this->lastParagraphStyle = '';
} }
} else { } else {
$this->_lastParagraphStyle = ''; $this->lastParagraphStyle = '';
} }
if ($styleFont instanceof Font) { if ($styleFont instanceof Font) {
if ($styleFont->getColor() != null) { if ($styleFont->getColor() != null) {
$idxColor = array_search($styleFont->getColor(), $this->_colorTable); $idxColor = array_search($styleFont->getColor(), $this->colorTable);
if ($idxColor !== false) { if ($idxColor !== false) {
$sRTFText .= '\cf' . ($idxColor + 1); $sRTFText .= '\cf' . ($idxColor + 1);
} }
@ -428,7 +380,7 @@ class RTF implements IWriter
$sRTFText .= '\cf0'; $sRTFText .= '\cf0';
} }
if ($styleFont->getName() != null) { if ($styleFont->getName() != null) {
$idxFont = array_search($styleFont->getName(), $this->_fontTable); $idxFont = array_search($styleFont->getName(), $this->fontTable);
if ($idxFont !== false) { if ($idxFont !== false) {
$sRTFText .= '\f' . $idxFont; $sRTFText .= '\f' . $idxFont;
} }
@ -445,7 +397,7 @@ class RTF implements IWriter
$sRTFText .= '\fs' . ($styleFont->getSize() * 2); $sRTFText .= '\fs' . ($styleFont->getSize() * 2);
} }
} }
if ($this->_lastParagraphStyle != '' || $styleFont) { if ($this->lastParagraphStyle != '' || $styleFont) {
$sRTFText .= ' '; $sRTFText .= ' ';
} }
$sRTFText .= $text->getText(); $sRTFText .= $text->getText();
@ -501,7 +453,7 @@ class RTF implements IWriter
*/ */
private function getDataContentTextBreak() private function getDataContentTextBreak()
{ {
$this->_lastParagraphStyle = ''; $this->lastParagraphStyle = '';
return '\par' . \PHP_EOL; return '\par' . \PHP_EOL;
} }

View File

@ -27,36 +27,8 @@ use PhpOffice\PhpWord\Writer\Word2007\Styles;
/** /**
* Word2007 writer * Word2007 writer
*/ */
class Word2007 implements IWriter class Word2007 extends Writer implements IWriter
{ {
/**
* PHPWord object
*
* @var PhpOffice\PhpWord\PhpWord
*/
private $_document;
/**
* Individual writers
*
* @var PhpOffice\PhpWord\Writer\Word2007\WriterPart
*/
private $_writerParts;
/**
* Disk caching directory
*
* @var string
*/
private $_diskCachingDirectory;
/**
* Use disk caching
*
* @var boolean
*/
private $_useDiskCaching = false;
/** /**
* Types of images * Types of images
* *
@ -78,22 +50,21 @@ class Word2007 implements IWriter
*/ */
public function __construct(PhpWord $phpWord = null) public function __construct(PhpWord $phpWord = null)
{ {
$this->_document = $phpWord; // Assign PhpWord
$this->setPhpWord($phpWord);
$this->_diskCachingDirectory = './'; // Set writer parts
$this->writerParts['contenttypes'] = new ContentTypes();
$this->_writerParts['contenttypes'] = new ContentTypes(); $this->writerParts['rels'] = new Rels();
$this->_writerParts['rels'] = new Rels(); $this->writerParts['docprops'] = new DocProps();
$this->_writerParts['docprops'] = new DocProps(); $this->writerParts['documentrels'] = new DocumentRels();
$this->_writerParts['documentrels'] = new DocumentRels(); $this->writerParts['document'] = new Document();
$this->_writerParts['document'] = new Document(); $this->writerParts['styles'] = new Styles();
$this->_writerParts['styles'] = new Styles(); $this->writerParts['header'] = new Header();
$this->_writerParts['header'] = new Header(); $this->writerParts['footer'] = new Footer();
$this->_writerParts['footer'] = new Footer(); $this->writerParts['footnotes'] = new Footnotes();
$this->_writerParts['footnotes'] = new Footnotes(); $this->writerParts['footnotesrels'] = new FootnotesRels();
$this->_writerParts['footnotesrels'] = new FootnotesRels(); foreach ($this->writerParts as $writer) {
foreach ($this->_writerParts as $writer) {
$writer->setParentWriter($this); $writer->setParentWriter($this);
} }
} }
@ -105,16 +76,8 @@ class Word2007 implements IWriter
*/ */
public function save($pFilename = null) public function save($pFilename = null)
{ {
if (!is_null($this->_document)) { if (!is_null($this->phpWord)) {
$pFilename = $this->getTempFile($pFilename);
// If $pFilename is php://output or php://stdout, make it a temporary file...
$originalFilename = $pFilename;
if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
$pFilename = @tempnam(sys_get_temp_dir(), 'phpword_');
if ($pFilename == '') {
$pFilename = $originalFilename;
}
}
// Create new ZIP file and open it for writing // Create new ZIP file and open it for writing
$objZip = new \ZipArchive(); $objZip = new \ZipArchive();
@ -126,12 +89,11 @@ class Word2007 implements IWriter
} }
} }
$sectionElements = array(); $sectionElements = array();
$_secElements = Media::getSectionMediaElements(); $_secElements = Media::getSectionMediaElements();
foreach ($_secElements as $element) { // loop through section media elements foreach ($_secElements as $element) { // loop through section media elements
if ($element['type'] != 'hyperlink') { if ($element['type'] != 'hyperlink') {
$this->_addFileToPackage($objZip, $element); $this->addFileToPackage($objZip, $element);
} }
$sectionElements[] = $element; $sectionElements[] = $element;
} }
@ -141,7 +103,7 @@ class Word2007 implements IWriter
if (count($_hdrMedia) > 0) { if (count($_hdrMedia) > 0) {
$objZip->addFromString('word/_rels/' . $_headerFile . '.xml.rels', $this->getWriterPart('documentrels')->writeHeaderFooterRels($_hdrMedia)); $objZip->addFromString('word/_rels/' . $_headerFile . '.xml.rels', $this->getWriterPart('documentrels')->writeHeaderFooterRels($_hdrMedia));
foreach ($_hdrMedia as $element) { // loop through header media elements foreach ($_hdrMedia as $element) { // loop through header media elements
$this->_addFileToPackage($objZip, $element); $this->addFileToPackage($objZip, $element);
} }
} }
} }
@ -151,7 +113,7 @@ class Word2007 implements IWriter
if (count($_ftrMedia) > 0) { if (count($_ftrMedia) > 0) {
$objZip->addFromString('word/_rels/' . $_footerFile . '.xml.rels', $this->getWriterPart('documentrels')->writeHeaderFooterRels($_ftrMedia)); $objZip->addFromString('word/_rels/' . $_footerFile . '.xml.rels', $this->getWriterPart('documentrels')->writeHeaderFooterRels($_ftrMedia));
foreach ($_ftrMedia as $element) { // loop through footers media elements foreach ($_ftrMedia as $element) { // loop through footers media elements
$this->_addFileToPackage($objZip, $element); $this->addFileToPackage($objZip, $element);
} }
} }
} }
@ -166,7 +128,7 @@ class Word2007 implements IWriter
$_cHdrs = 0; $_cHdrs = 0;
$_cFtrs = 0; $_cFtrs = 0;
$rID = Media::countSectionMediaElements() + 6; $rID = Media::countSectionMediaElements() + 6;
$_sections = $this->_document->getSections(); $_sections = $this->phpWord->getSections();
$footers = array(); $footers = array();
foreach ($_sections as $section) { foreach ($_sections as $section) {
@ -211,12 +173,12 @@ class Word2007 implements IWriter
$footers $footers
) )
); );
$objZip->addFromString('_rels/.rels', $this->getWriterPart('rels')->writeRelationships($this->_document)); $objZip->addFromString('_rels/.rels', $this->getWriterPart('rels')->writeRelationships($this->phpWord));
$objZip->addFromString('docProps/app.xml', $this->getWriterPart('docprops')->writeDocPropsApp($this->_document)); $objZip->addFromString('docProps/app.xml', $this->getWriterPart('docprops')->writeDocPropsApp($this->phpWord));
$objZip->addFromString('docProps/core.xml', $this->getWriterPart('docprops')->writeDocPropsCore($this->_document)); $objZip->addFromString('docProps/core.xml', $this->getWriterPart('docprops')->writeDocPropsCore($this->phpWord));
$objZip->addFromString('word/document.xml', $this->getWriterPart('document')->writeDocument($this->_document)); $objZip->addFromString('word/document.xml', $this->getWriterPart('document')->writeDocument($this->phpWord));
$objZip->addFromString('word/_rels/document.xml.rels', $this->getWriterPart('documentrels')->writeDocumentRels($sectionElements)); $objZip->addFromString('word/_rels/document.xml.rels', $this->getWriterPart('documentrels')->writeDocumentRels($sectionElements));
$objZip->addFromString('word/styles.xml', $this->getWriterPart('styles')->writeStyles($this->_document)); $objZip->addFromString('word/styles.xml', $this->getWriterPart('styles')->writeStyles($this->phpWord));
// Write static files // Write static files
$objZip->addFile(__DIR__ . '/../_staticDocParts/numbering.xml', 'word/numbering.xml'); $objZip->addFile(__DIR__ . '/../_staticDocParts/numbering.xml', 'word/numbering.xml');
@ -225,19 +187,12 @@ class Word2007 implements IWriter
$objZip->addFile(__DIR__ . '/../_staticDocParts/webSettings.xml', 'word/webSettings.xml'); $objZip->addFile(__DIR__ . '/../_staticDocParts/webSettings.xml', 'word/webSettings.xml');
$objZip->addFile(__DIR__ . '/../_staticDocParts/fontTable.xml', 'word/fontTable.xml'); $objZip->addFile(__DIR__ . '/../_staticDocParts/fontTable.xml', 'word/fontTable.xml');
// Close file // Close file
if ($objZip->close() === false) { if ($objZip->close() === false) {
throw new Exception("Could not close zip file $pFilename."); throw new Exception("Could not close zip file $pFilename.");
} }
// If a temporary file was used, copy it to the correct file stream $this->cleanupTempFile();
if ($originalFilename != $pFilename) {
if (copy($pFilename, $originalFilename) === false) {
throw new Exception("Could not copy temporary zip file $pFilename to $originalFilename.");
}
@unlink($pFilename);
}
} else { } else {
throw new Exception("PhpWord object unassigned."); throw new Exception("PhpWord object unassigned.");
} }
@ -290,69 +245,13 @@ class Word2007 implements IWriter
} }
} }
/**
* Get writer part
*
* @param string $pPartName Writer part name
* @return \PhpOffice\PhpWord\Writer\ODText\WriterPart
*/
public function getWriterPart($pPartName = '')
{
if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) {
return $this->_writerParts[strtolower($pPartName)];
} else {
return null;
}
}
/**
* Get use disk caching status
*
* @return boolean
*/
public function getUseDiskCaching()
{
return $this->_useDiskCaching;
}
/**
* Set use disk caching status
*
* @param boolean $pValue
* @param string $pDirectory
*/
public function setUseDiskCaching($pValue = false, $pDirectory = null)
{
$this->_useDiskCaching = $pValue;
if (!is_null($pDirectory)) {
if (is_dir($pDirectory)) {
$this->_diskCachingDirectory = $pDirectory;
} else {
throw new Exception("Directory does not exist: $pDirectory");
}
}
return $this;
}
/**
* Get disk caching directory
*
* @return string
*/
public function getDiskCachingDirectory()
{
return $this->_diskCachingDirectory;
}
/** /**
* Check content types * Check content types
* *
* @param mixed $objZip * @param mixed $objZip
* @param mixed $element * @param mixed $element
*/ */
private function _addFileToPackage($objZip, $element) private function addFileToPackage($objZip, $element)
{ {
if (isset($element['isMemImage']) && $element['isMemImage']) { if (isset($element['isMemImage']) && $element['isMemImage']) {
$image = call_user_func($element['createfunction'], $element['source']); $image = call_user_func($element['createfunction'], $element['source']);

View File

@ -27,12 +27,7 @@ class ContentTypes extends WriterPart
public function writeContentTypes($_imageTypes, $_objectTypes, $_cHdrs, $footers) public function writeContentTypes($_imageTypes, $_objectTypes, $_cHdrs, $footers)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');

View File

@ -23,12 +23,7 @@ class DocProps extends WriterPart
public function writeDocPropsApp(PhpWord $phpWord = null) public function writeDocPropsApp(PhpWord $phpWord = null)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');
@ -120,12 +115,7 @@ class DocProps extends WriterPart
public function writeDocPropsCore(PhpWord $phpWord = null) public function writeDocPropsCore(PhpWord $phpWord = null)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');

View File

@ -41,11 +41,7 @@ class Document extends Base
public function writeDocument(PhpWord $phpWord = null) public function writeDocument(PhpWord $phpWord = null)
{ {
// Create XML writer // Create XML writer
if ($this->getParentWriter()->getUseDiskCaching()) { $xmlWriter = $this->getXmlWriter();
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');

View File

@ -25,12 +25,7 @@ class DocumentRels extends WriterPart
public function writeDocumentRels($_relsCollection) public function writeDocumentRels($_relsCollection)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');
@ -118,12 +113,7 @@ class DocumentRels extends WriterPart
public function writeHeaderFooterRels($_relsCollection) public function writeHeaderFooterRels($_relsCollection)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');

View File

@ -30,12 +30,7 @@ class Footer extends Base
public function writeFooter(\PhpOffice\PhpWord\Section\Footer $footer) public function writeFooter(\PhpOffice\PhpWord\Section\Footer $footer)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');

View File

@ -29,15 +29,8 @@ class Footnotes extends Base
public function writeFootnotes($allFootnotesCollection) public function writeFootnotes($allFootnotesCollection)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(
XMLWriter::STORAGE_DISK,
$this->getParentWriter()->getDiskCachingDirectory()
);
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');
$xmlWriter->startElement('w:footnotes'); $xmlWriter->startElement('w:footnotes');

View File

@ -25,12 +25,7 @@ class FootnotesRels extends WriterPart
public function writeFootnotesRels($_relsCollection) public function writeFootnotesRels($_relsCollection)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');

View File

@ -30,11 +30,7 @@ class Header extends Base
public function writeHeader(\PhpOffice\PhpWord\Section\Header $header) public function writeHeader(\PhpOffice\PhpWord\Section\Header $header)
{ {
// Create XML writer // Create XML writer
if ($this->getParentWriter()->getUseDiskCaching()) { $xmlWriter = $this->getXmlWriter();
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');

View File

@ -26,12 +26,7 @@ class Rels extends WriterPart
public function writeRelationships(PhpWord $phpWord = null) public function writeRelationships(PhpWord $phpWord = null)
{ {
// Create XML writer // Create XML writer
$xmlWriter = null; $xmlWriter = $this->getXmlWriter();
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');

View File

@ -34,17 +34,11 @@ class Styles extends Base
*/ */
public function writeStyles(PhpWord $phpWord = null) public function writeStyles(PhpWord $phpWord = null)
{ {
// Create XML writer
$xmlWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
$xmlWriter = new XMLWriter(
XMLWriter::STORAGE_DISK,
$this->getParentWriter()->getDiskCachingDirectory()
);
} else {
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
$this->phpWord = $phpWord; $this->phpWord = $phpWord;
// Create XML writer
$xmlWriter = $this->getXmlWriter();
// XML header // XML header
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startDocument('1.0', 'UTF-8', 'yes');
$xmlWriter->startElement('w:styles'); $xmlWriter->startElement('w:styles');

View File

@ -11,6 +11,7 @@ namespace PhpOffice\PhpWord\Writer\Word2007;
use PhpOffice\PhpWord\Exceptions\Exception; use PhpOffice\PhpWord\Exceptions\Exception;
use PhpOffice\PhpWord\Writer\IWriter; use PhpOffice\PhpWord\Writer\IWriter;
use PhpOffice\PhpWord\Shared\XMLWriter;
/** /**
* Word2007 writer part abstract class * Word2007 writer part abstract class
@ -22,7 +23,7 @@ abstract class WriterPart
* *
* @var IWriter * @var IWriter
*/ */
private $_parentWriter; protected $parentWriter;
/** /**
* Set parent writer * Set parent writer
@ -31,20 +32,41 @@ abstract class WriterPart
*/ */
public function setParentWriter(IWriter $pWriter = null) public function setParentWriter(IWriter $pWriter = null)
{ {
$this->_parentWriter = $pWriter; $this->parentWriter = $pWriter;
} }
/** /**
* Get parent writer * Get parent writer
* *
* @return IWriter * @return IWriter
* @throws Exception
*/ */
public function getParentWriter() public function getParentWriter()
{ {
if (!is_null($this->_parentWriter)) { if (!is_null($this->parentWriter)) {
return $this->_parentWriter; return $this->parentWriter;
} else { } else {
throw new Exception("No parent IWriter assigned."); throw new Exception("No parent IWriter assigned.");
} }
} }
/**
* Get XML Writer
*
* @return XMLWriter
*/
protected function getXmlWriter()
{
$useDiskCaching = false;
if (!is_null($this->parentWriter)) {
if ($this->parentWriter->getUseDiskCaching()) {
$useDiskCaching = true;
}
}
if ($useDiskCaching) {
return new XMLWriter(XMLWriter::STORAGE_DISK, $this->parentWriter->getDiskCachingDirectory());
} else {
return new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
}
} }

View File

@ -0,0 +1,184 @@
<?php
/**
* PHPWord
*
* @link https://github.com/PHPOffice/PHPWord
* @copyright 2014 PHPWord
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
*/
namespace PhpOffice\PhpWord\Writer;
use PhpOffice\PhpWord\Exceptions\Exception;
use PhpOffice\PhpWord\PhpWord;
/**
* Abstract writer class
*
* @since 0.9.2
*/
abstract class Writer implements IWriter
{
/**
* PHPWord object
*
* @var PhpOffice\PhpWord\PhpWord
*/
protected $phpWord = null;
/**
* Individual writers
*
* @var mixed
*/
protected $writerParts = array();
/**
* Use disk caching
*
* @var boolean
*/
private $useDiskCaching = false;
/**
* Disk caching directory
*
* @var string
*/
private $diskCachingDirectory = './';
/**
* Original file name
*
* @var string
*/
private $originalFilename;
/**
* Temporary file name
*
* @var string
*/
private $tempFilename;
/**
* Get PhpWord object
*
* @return PhpWord
* @throws Exception
*/
public function getPhpWord()
{
if (!is_null($this->phpWord)) {
return $this->phpWord;
} else {
throw new Exception("No PhpWord assigned.");
}
}
/**
* Set PhpWord object
*
* @param PhpWord
* @return $this
*/
public function setPhpWord(PhpWord $phpWord = null)
{
$this->phpWord = $phpWord;
return $this;
}
/**
* Get writer part
*
* @param string $pPartName Writer part name
* @return mixed
*/
public function getWriterPart($pPartName = '')
{
if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) {
return $this->writerParts[strtolower($pPartName)];
} else {
return null;
}
}
/**
* Get use disk caching status
*
* @return boolean
*/
public function getUseDiskCaching()
{
return $this->useDiskCaching;
}
/**
* Set use disk caching status
*
* @param boolean $pValue
* @param string $pDirectory
* @return $this
*/
public function setUseDiskCaching($pValue = false, $pDirectory = null)
{
$this->useDiskCaching = $pValue;
if (!is_null($pDirectory)) {
if (is_dir($pDirectory)) {
$this->diskCachingDirectory = $pDirectory;
} else {
throw new Exception("Directory does not exist: $pDirectory");
}
}
return $this;
}
/**
* Get disk caching directory
*
* @return string
*/
public function getDiskCachingDirectory()
{
return $this->diskCachingDirectory;
}
/**
* Get temporary file name
*
* If $pFilename is php://output or php://stdout, make it a temporary file
*
* @param string $pFilename
* @return string
*/
protected function getTempFile($pFilename)
{
$this->originalFilename = $pFilename;
if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
$pFilename = @tempnam(sys_get_temp_dir(), 'phpword_');
if ($pFilename == '') {
$pFilename = $this->originalFilename;
}
}
$this->tempFilename = $pFilename;
return $this->tempFilename;
}
/**
* Cleanup temporary file
*
* If a temporary file was used, copy it to the correct file stream
*/
protected function cleanupTempFile()
{
if ($this->originalFilename != $this->tempFilename) {
if (copy($this->tempFilename, $this->originalFilename) === false) {
throw new Exception("Could not copy temporary zip file {$this->tempFilename} to {$this->originalFilename}.");
}
@unlink($this->tempFilename);
}
}
}