diff --git a/src/PhpWord/Autoloader.php b/src/PhpWord/Autoloader.php
index 6acfff21..c60ae9a6 100644
--- a/src/PhpWord/Autoloader.php
+++ b/src/PhpWord/Autoloader.php
@@ -46,6 +46,7 @@ class Autoloader
$file = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, $prefixLength));
$file = realpath(__DIR__ . (empty($file) ? '' : DIRECTORY_SEPARATOR) . $file . '.php');
if (file_exists($file)) {
+ /** @noinspection PhpIncludeInspection Dynamic includes */
require_once $file;
}
}
diff --git a/src/PhpWord/Reader/Word2007/Document.php b/src/PhpWord/Reader/Word2007/Document.php
index 224c895e..80d2dde2 100644
--- a/src/PhpWord/Reader/Word2007/Document.php
+++ b/src/PhpWord/Reader/Word2007/Document.php
@@ -158,7 +158,9 @@ class Document extends AbstractPart
// Section properties
if ($xmlReader->elementExists('w:pPr/w:sectPr', $node)) {
$sectPrNode = $xmlReader->getElement('w:pPr/w:sectPr', $node);
- $this->readWSectPrNode($xmlReader, $sectPrNode, $section);
+ if ($sectPrNode !== null) {
+ $this->readWSectPrNode($xmlReader, $sectPrNode, $section);
+ }
$section = $this->phpWord->addSection();
}
}
@@ -172,10 +174,8 @@ class Document extends AbstractPart
*/
private function readWSectPrNode(XMLReader $xmlReader, \DOMElement $node, Section &$section)
{
- if ($node !== null) {
- $settings = $this->readSectionStyle($xmlReader, $node);
- $section->setSettings($settings);
- $this->readHeaderFooter($settings, $section);
- }
+ $settings = $this->readSectionStyle($xmlReader, $node);
+ $section->setSettings($settings);
+ $this->readHeaderFooter($settings, $section);
}
}
diff --git a/src/PhpWord/Shared/String.php b/src/PhpWord/Shared/String.php
index 259e904c..99b8cca3 100644
--- a/src/PhpWord/Shared/String.php
+++ b/src/PhpWord/Shared/String.php
@@ -86,14 +86,28 @@ class String
}
/**
- * Returns unicode from UTF8 text
+ * Returns unicode array from UTF8 text
+ *
+ * The function is splitted to reduce cyclomatic complexity
*
* @param string $text UTF8 text
* @return string Unicode text
* @since 0.11.0
- * @link http://www.randomchaos.com/documents/?source=php_and_unicode
*/
public static function toUnicode($text)
+ {
+ return self::unicodeToEntities(self::utf8ToUnicode($text));
+ }
+
+ /**
+ * Returns unicode from UTF8 text
+ *
+ * @param string $text UTF8 text
+ * @return array
+ * @since 0.11.0
+ * @link http://www.randomchaos.com/documents/?source=php_and_unicode
+ */
+ private static function utf8ToUnicode($text)
{
$unicode = array();
$values = array();
@@ -122,8 +136,21 @@ class String
}
}
- // Converts text with utf8 characters into rtf utf8 entites preserving ascii
+ return $unicode;
+ }
+
+ /**
+ * Returns entites from unicode array
+ *
+ * @param array $unicode
+ * @return string
+ * @since 0.11.0
+ * @link http://www.randomchaos.com/documents/?source=php_and_unicode
+ */
+ private static function unicodeToEntities($unicode)
+ {
$entities = '';
+
foreach ($unicode as $value) {
if ($value != 65279) {
$entities .= $value > 127 ? '\uc0{\u' . $value . '}' : chr($value);
diff --git a/src/PhpWord/Writer/HTML.php b/src/PhpWord/Writer/HTML.php
index 98cab55e..88e7658d 100644
--- a/src/PhpWord/Writer/HTML.php
+++ b/src/PhpWord/Writer/HTML.php
@@ -19,15 +19,6 @@ namespace PhpOffice\PhpWord\Writer;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\PhpWord;
-use PhpOffice\PhpWord\Settings;
-use PhpOffice\PhpWord\Style;
-use PhpOffice\PhpWord\Style\Font;
-use PhpOffice\PhpWord\Style\Paragraph;
-use PhpOffice\PhpWord\Writer\HTML\Element\Container;
-use PhpOffice\PhpWord\Writer\HTML\Element\TextRun as TextRunWriter;
-use PhpOffice\PhpWord\Writer\HTML\Style\Font as FontStyleWriter;
-use PhpOffice\PhpWord\Writer\HTML\Style\Generic as GenericStyleWriter;
-use PhpOffice\PhpWord\Writer\HTML\Style\Paragraph as ParagraphStyleWriter;
/**
* HTML writer
@@ -57,6 +48,17 @@ class HTML extends AbstractWriter implements WriterInterface
public function __construct(PhpWord $phpWord = null)
{
$this->setPhpWord($phpWord);
+
+ $this->parts = array('Head', 'Body');
+ foreach ($this->parts as $partName) {
+ $partClass = 'PhpOffice\\PhpWord\\Writer\\HTML\\Part\\' . $partName;
+ if (class_exists($partClass)) {
+ /** @var \PhpOffice\PhpWord\Writer\HTML\Part\AbstractPart $part Type hint */
+ $part = new $partClass();
+ $part->setParentWriter($this);
+ $this->writerParts[strtolower($partName)] = $part;
+ }
+ }
}
/**
@@ -89,164 +91,13 @@ class HTML extends AbstractWriter implements WriterInterface
$content .= '' . PHP_EOL;
$content .= '' . PHP_EOL;
$content .= '' . PHP_EOL;
- $content .= '
' . PHP_EOL;
- $content .= $this->writeHead();
- $content .= '' . PHP_EOL;
- $content .= '' . PHP_EOL;
- $content .= $this->writeBody();
- $content .= $this->writeNotes();
- $content .= '' . PHP_EOL;
+ $content .= $this->getWriterPart('Head')->write();
+ $content .= $this->getWriterPart('Body')->write();
$content .= '' . PHP_EOL;
return $content;
}
- /**
- * Generate HTML header
- *
- * @return string
- */
- private function writeHead()
- {
- $phpWord = $this->getPhpWord();
- $properties = $phpWord->getDocumentProperties();
- $propertiesMapping = array(
- 'creator' => 'author',
- 'title' => '',
- 'description' => '',
- 'subject' => '',
- 'keywords' => '',
- 'category' => '',
- 'company' => '',
- 'manager' => ''
- );
- $title = $properties->getTitle();
- $title = ($title != '') ? $title : 'PHPWord';
-
- $content = '';
- $content .= '' . PHP_EOL;
- $content .= '' . htmlspecialchars($title) . '' . PHP_EOL;
- foreach ($propertiesMapping as $key => $value) {
- $value = ($value == '') ? $key : $value;
- $method = "get" . $key;
- if ($properties->$method() != '') {
- $content .= '' . PHP_EOL;
- }
- }
- $content .= $this->writeStyles();
-
- return $content;
- }
-
- /**
- * Get content
- *
- * @return string
- */
- private function writeBody()
- {
- $phpWord = $this->getPhpWord();
- $content = '';
-
- $sections = $phpWord->getSections();
- $countSections = count($sections);
-
- if ($countSections > 0) {
- foreach ($sections as $section) {
- $writer = new Container($this, $section);
- $content .= $writer->write();
- }
- }
-
- return $content;
- }
-
- /**
- * Get styles
- *
- * @return string
- */
- private function writeStyles()
- {
- $css = '' . PHP_EOL;
-
- return $css;
- }
-
- /**
- * Write footnote/endnote contents as textruns
- */
- private function writeNotes()
- {
- $phpWord = $this->getPhpWord();
- $content = PHP_EOL;
-
- if (!empty($this->notes)) {
- $content .= "
" . PHP_EOL;
- foreach ($this->notes as $noteId => $noteMark) {
- list($noteType, $noteTypeId) = explode('-', $noteMark);
- $method = 'get' . ($noteType == 'endnote' ? 'Endnotes' : 'Footnotes');
- $collection = $phpWord->$method()->getItems();
-
- if (array_key_exists($noteTypeId, $collection)) {
- $element = $collection[$noteTypeId];
- $noteAnchor = "";
- $noteAnchor .= "{$noteId}";
-
- $writer = new TextRunWriter($this, $element);
- $writer->setOpeningText($noteAnchor);
- $content .= $writer->write();
- }
- }
- }
-
- return $content;
- }
-
/**
* Get is PDF
*
diff --git a/src/PhpWord/Writer/HTML/Element/Image.php b/src/PhpWord/Writer/HTML/Element/Image.php
index dafc1c38..698b7e86 100644
--- a/src/PhpWord/Writer/HTML/Element/Image.php
+++ b/src/PhpWord/Writer/HTML/Element/Image.php
@@ -88,7 +88,7 @@ class Image extends Text
} else {
$actualSource = $source;
}
- if (is_null($actualSource)) {
+ if ($actualSource === null) {
return null;
}
@@ -100,12 +100,13 @@ class Image extends Text
$imageBinary = ob_get_contents();
ob_end_clean();
} else {
- if ($fileHandle = fopen($actualSource, 'rb', false)) {
+ $fileHandle = fopen($actualSource, 'rb', false);
+ if ($fileHandle !== false) {
$imageBinary = fread($fileHandle, filesize($actualSource));
fclose($fileHandle);
}
}
- if (!is_null($imageBinary)) {
+ if ($imageBinary !== null) {
$base64 = chunk_split(base64_encode($imageBinary));
$imageData = 'data:' . $imageType . ';base64,' . $base64;
}
diff --git a/src/PhpWord/Writer/HTML/Part/AbstractPart.php b/src/PhpWord/Writer/HTML/Part/AbstractPart.php
new file mode 100644
index 00000000..319aa20f
--- /dev/null
+++ b/src/PhpWord/Writer/HTML/Part/AbstractPart.php
@@ -0,0 +1,68 @@
+parentWriter = $writer;
+ }
+
+ /**
+ * Get parent writer
+ *
+ * @return \PhpOffice\PhpWord\Writer\AbstractWriter
+ * @throws \PhpOffice\PhpWord\Exception\Exception
+ */
+ public function getParentWriter()
+ {
+ if ($this->parentWriter !== null) {
+ return $this->parentWriter;
+ } else {
+ throw new Exception('No parent WriterInterface assigned.');
+ }
+ }
+}
diff --git a/src/PhpWord/Writer/HTML/Part/Body.php b/src/PhpWord/Writer/HTML/Part/Body.php
new file mode 100644
index 00000000..4fd61a83
--- /dev/null
+++ b/src/PhpWord/Writer/HTML/Part/Body.php
@@ -0,0 +1,89 @@
+getParentWriter()->getPhpWord();
+
+ $content = '';
+
+ $content .= '' . PHP_EOL;
+ $sections = $phpWord->getSections();
+ foreach ($sections as $section) {
+ $writer = new Container($this->getParentWriter(), $section);
+ $content .= $writer->write();
+ }
+
+ $content .= $this->writeNotes();
+ $content .= '' . PHP_EOL;
+
+ return $content;
+ }
+
+ /**
+ * Write footnote/endnote contents as textruns
+ *
+ * @return string
+ */
+ private function writeNotes()
+ {
+ /** @var \PhpOffice\PhpWord\Writer\HTML $parentWriter Type hint */
+ $parentWriter = $this->getParentWriter();
+ $phpWord = $parentWriter->getPhpWord();
+ $notes = $parentWriter->getNotes();
+
+ $content = '';
+
+ if (!empty($notes)) {
+ $content .= "
" . PHP_EOL;
+ foreach ($notes as $noteId => $noteMark) {
+ list($noteType, $noteTypeId) = explode('-', $noteMark);
+ $method = 'get' . ($noteType == 'endnote' ? 'Endnotes' : 'Footnotes');
+ $collection = $phpWord->$method()->getItems();
+
+ if (array_key_exists($noteTypeId, $collection)) {
+ $element = $collection[$noteTypeId];
+ $noteAnchor = "";
+ $noteAnchor .= "{$noteId}";
+
+ $writer = new TextRunWriter($this->getParentWriter(), $element);
+ $writer->setOpeningText($noteAnchor);
+ $content .= $writer->write();
+ }
+ }
+ }
+
+ return $content;
+ }
+}
diff --git a/src/PhpWord/Writer/HTML/Part/Head.php b/src/PhpWord/Writer/HTML/Part/Head.php
new file mode 100644
index 00000000..389d568b
--- /dev/null
+++ b/src/PhpWord/Writer/HTML/Part/Head.php
@@ -0,0 +1,129 @@
+getParentWriter()->getPhpWord()->getDocumentProperties();
+ $propertiesMapping = array(
+ 'creator' => 'author',
+ 'title' => '',
+ 'description' => '',
+ 'subject' => '',
+ 'keywords' => '',
+ 'category' => '',
+ 'company' => '',
+ 'manager' => ''
+ );
+ $title = $docProps->getTitle();
+ $title = ($title != '') ? $title : 'PHPWord';
+
+ $content = '';
+
+ $content .= '' . PHP_EOL;
+ $content .= '' . PHP_EOL;
+ $content .= '' . htmlspecialchars($title) . '' . PHP_EOL;
+ foreach ($propertiesMapping as $key => $value) {
+ $value = ($value == '') ? $key : $value;
+ $method = "get" . $key;
+ if ($docProps->$method() != '') {
+ $content .= '' . PHP_EOL;
+ }
+ }
+ $content .= $this->writeStyles();
+ $content .= '' . PHP_EOL;
+
+ return $content;
+ }
+ /**
+ * Get styles
+ *
+ * @return string
+ */
+ private function writeStyles()
+ {
+ $css = '' . PHP_EOL;
+
+ return $css;
+ }
+}
diff --git a/src/PhpWord/Writer/PDF/AbstractRenderer.php b/src/PhpWord/Writer/PDF/AbstractRenderer.php
index f7266d1a..83b02251 100644
--- a/src/PhpWord/Writer/PDF/AbstractRenderer.php
+++ b/src/PhpWord/Writer/PDF/AbstractRenderer.php
@@ -84,6 +84,7 @@ abstract class AbstractRenderer extends HTML
parent::__construct($phpWord);
$includeFile = Settings::getPdfRendererPath() . '/' . $this->includeFile;
if (file_exists($includeFile)) {
+ /** @noinspection PhpIncludeInspection Dynamic includes */
require_once $includeFile;
} else {
throw new Exception('Unable to load PDF Rendering library');
diff --git a/src/PhpWord/Writer/RTF.php b/src/PhpWord/Writer/RTF.php
index aaf412de..ef94b264 100644
--- a/src/PhpWord/Writer/RTF.php
+++ b/src/PhpWord/Writer/RTF.php
@@ -35,7 +35,8 @@ class RTF extends AbstractWriter implements WriterInterface
private $lastParagraphStyle;
/**
- * Create new RTF writer
+ * Create new instance
+ *
* @param \PhpOffice\PhpWord\PhpWord $phpWord
*/
public function __construct(PhpWord $phpWord = null)
@@ -52,7 +53,6 @@ class RTF extends AbstractWriter implements WriterInterface
$this->writerParts[strtolower($partName)] = $part;
}
}
-
}
/**
diff --git a/src/PhpWord/Writer/RTF/Part/AbstractPart.php b/src/PhpWord/Writer/RTF/Part/AbstractPart.php
index 3a73a226..b10e5654 100644
--- a/src/PhpWord/Writer/RTF/Part/AbstractPart.php
+++ b/src/PhpWord/Writer/RTF/Part/AbstractPart.php
@@ -17,52 +17,13 @@
namespace PhpOffice\PhpWord\Writer\RTF\Part;
-use PhpOffice\PhpWord\Exception\Exception;
-use PhpOffice\PhpWord\Writer\AbstractWriter;
+use PhpOffice\PhpWord\Writer\HTML\Part\AbstractPart as HTMLAbstractPart;
/**
* Abstract RTF part writer
*
* @since 0.11.0
*/
-abstract class AbstractPart
+abstract class AbstractPart extends HTMLAbstractPart
{
- /**
- * Parent writer
- *
- * @var \PhpOffice\PhpWord\Writer\AbstractWriter
- */
- private $parentWriter;
-
- /**
- * Write part
- *
- * @return string
- */
- abstract public function write();
-
- /**
- * Set parent writer
- *
- * @param \PhpOffice\PhpWord\Writer\AbstractWriter $writer
- */
- public function setParentWriter(AbstractWriter $writer = null)
- {
- $this->parentWriter = $writer;
- }
-
- /**
- * Get parent writer
- *
- * @return \PhpOffice\PhpWord\Writer\AbstractWriter
- * @throws \PhpOffice\PhpWord\Exception\Exception
- */
- public function getParentWriter()
- {
- if ($this->parentWriter !== null) {
- return $this->parentWriter;
- } else {
- throw new Exception('No parent WriterInterface assigned.');
- }
- }
}
diff --git a/src/PhpWord/Writer/Word2007/Element/Container.php b/src/PhpWord/Writer/Word2007/Element/Container.php
index 7d1c8104..3dad824d 100644
--- a/src/PhpWord/Writer/Word2007/Element/Container.php
+++ b/src/PhpWord/Writer/Word2007/Element/Container.php
@@ -17,8 +17,10 @@
namespace PhpOffice\PhpWord\Writer\Word2007\Element;
+use PhpOffice\PhpWord\Element\AbstractElement as Element;
use PhpOffice\PhpWord\Element\AbstractContainer as ContainerElement;
use PhpOffice\PhpWord\Element\TextBreak as TextBreakElement;
+use PhpOffice\PhpWord\Shared\XMLWriter;
/**
* Container element writer (section, textrun, header, footnote, cell, etc.)
@@ -51,36 +53,52 @@ class Container extends AbstractElement
$elements = $container->getElements();
$elementClass = '';
foreach ($elements as $element) {
- $elementClass = substr(get_class($element), strrpos(get_class($element), '\\') + 1);
- $writerClass = $this->namespace . '\\' . $elementClass;
-
- // Check it's a page break. No need to write it, instead, flag containers' pageBreakBefore
- // to be assigned to the next element
- if ($elementClass == 'PageBreak') {
- $this->setPageBreakBefore(true);
- continue;
- }
- if (class_exists($writerClass)) {
- // Get container's page break before and reset it
- $pageBreakBefore = $this->hasPageBreakBefore();
- $this->setPageBreakBefore(false);
-
- /** @var \PhpOffice\PhpWord\Writer\Word2007\Element\AbstractElement $writer Type hint */
- $writer = new $writerClass($xmlWriter, $element, $withoutP);
- $writer->setPageBreakBefore($pageBreakBefore);
- $writer->write();
- }
+ $elementClass = $this->writeElement($xmlWriter, $element, $withoutP);
}
- // Special case for Cell: They have to contain a w:p element at the end. The $elementClass contains
- // the last element name. If it's empty string or Table, the last element is not w:p
- if ($containerClass == 'Cell') {
- if ($elementClass == '' || $elementClass == 'Table') {
- $writerClass = $this->namespace . '\\TextBreak';
- /** @var \PhpOffice\PhpWord\Writer\Word2007\Element\AbstractElement $writer Type hint */
- $writer = new $writerClass($xmlWriter, new TextBreakElement(), $withoutP);
- $writer->write();
- }
+ // Special case for Cell: They have to contain a w:p element at the end.
+ // The $elementClass contains the last element name. If it's empty string
+ // or Table, the last element is not w:p
+ $writeLastTextBreak = ($containerClass == 'Cell') && ($elementClass == '' || $elementClass == 'Table');
+ if ($writeLastTextBreak) {
+ $writerClass = $this->namespace . '\\TextBreak';
+ /** @var \PhpOffice\PhpWord\Writer\Word2007\Element\AbstractElement $writer Type hint */
+ $writer = new $writerClass($xmlWriter, new TextBreakElement(), $withoutP);
+ $writer->write();
}
}
+
+ /**
+ * Write individual element
+ *
+ * @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
+ * @param \PhpOffice\PhpWord\Element\AbstractElement $element
+ * @param bool $withoutP
+ * @return string
+ */
+ private function writeElement(XMLWriter $xmlWriter, Element $element, $withoutP)
+ {
+ $elementClass = substr(get_class($element), strrpos(get_class($element), '\\') + 1);
+ $writerClass = $this->namespace . '\\' . $elementClass;
+
+ // Check it's a page break. No need to write it, instead, flag containers'
+ // pageBreakBefore to be assigned to the next element
+ if ($elementClass == 'PageBreak') {
+ $this->setPageBreakBefore(true);
+ return $elementClass;
+ }
+
+ if (class_exists($writerClass)) {
+ // Get container's page break before and reset it
+ $pageBreakBefore = $this->hasPageBreakBefore();
+ $this->setPageBreakBefore(false);
+
+ /** @var \PhpOffice\PhpWord\Writer\Word2007\Element\AbstractElement $writer Type hint */
+ $writer = new $writerClass($xmlWriter, $element, $withoutP);
+ $writer->setPageBreakBefore($pageBreakBefore);
+ $writer->write();
+ }
+
+ return $elementClass;
+ }
}