Skip to content

Commit 1e9a498

Browse files
committed
1 parent 5ff47f4 commit 1e9a498

File tree

9 files changed

+166
-122
lines changed

9 files changed

+166
-122
lines changed

src/PhpWord/Element/AbstractContainer.php

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,38 +56,24 @@ protected function addElement($elementName)
5656

5757
// Get arguments
5858
$args = func_get_args();
59-
$argsCount = func_num_args();
6059
$withoutP = in_array($this->container, array('TextRun', 'Footnote', 'Endnote', 'ListItemRun'));
6160
if ($withoutP && ($elementName == 'Text' || $elementName == 'PreserveText')) {
62-
$args[3] = null;
61+
$args[3] = null; // Remove paragraph style for texts in textrun
6362
}
6463

65-
// Create element dynamically
66-
64+
// Create element using reflection
65+
$reflection = new \ReflectionClass($elementClass);
66+
$elementArgs = $args;
67+
array_shift($elementArgs); // Shift an element off the beginning of array: the $elementName
6768
/** @var \PhpOffice\PhpWord\Element\AbstractElement $element Type hint */
68-
if ($argsCount == 2) { // TextRun, TextBox, Table, Footnote, Endnote
69-
$element = new $elementClass($args[1]);
70-
} elseif ($argsCount == 3) { // Object, TextBreak, Title
71-
$element = new $elementClass($args[1], $args[2]);
72-
} elseif ($argsCount == 4) { // PreserveText, Text, Image
73-
$element = new $elementClass($args[1], $args[2], $args[3]);
74-
} elseif ($argsCount == 5) { // CheckBox, Link, ListItemRun, TOC
75-
$element = new $elementClass($args[1], $args[2], $args[3], $args[4]);
76-
} elseif ($argsCount == 6) { // ListItem
77-
$element = new $elementClass($args[1], $args[2], $args[3], $args[4], $args[5]);
78-
} else { // Page Break
79-
$element = new $elementClass();
80-
}
69+
$element = $reflection->newInstanceArgs($elementArgs);
8170

8271
// Set relation Id for media collection
8372
$mediaContainer = $this->getMediaContainer();
8473
if (in_array($elementName, array('Link', 'Image', 'Object'))) {
85-
if ($elementName == 'Image') {
86-
/** @var \PhpOffice\PhpWord\Element\Image $element Type hint */
87-
$rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1], $element);
88-
} else {
89-
$rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1]);
90-
}
74+
/** @var \PhpOffice\PhpWord\Element\Image $element Type hint */
75+
$image = ($elementName == 'Image') ? $element : null;
76+
$rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1], $image);
9177
$element->setRelationId($rId);
9278
}
9379
if ($elementName == 'Object') {

src/PhpWord/Element/Image.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,15 @@ public function setMediaIndex($value)
284284
*
285285
* @param bool $base64
286286
* @return string|null
287+
* @since 0.11.0
287288
*/
288289
public function getImageStringData($base64 = false)
289290
{
290291
$source = $this->source;
291292
$actualSource = null;
292293
$imageBinary = null;
293294
$imageData = null;
295+
$isTemp = false;
294296

295297
// Get actual source from archive image or other source
296298
// Return null if not found
@@ -301,6 +303,7 @@ public function getImageStringData($base64 = false)
301303
$zip = new ZipArchive();
302304
if ($zip->open($zipFilename) !== false) {
303305
if ($zip->locateName($imageFilename)) {
306+
$isTemp = true;
304307
$zip->extractTo(sys_get_temp_dir(), $imageFilename);
305308
$actualSource = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $imageFilename;
306309
}
@@ -313,7 +316,7 @@ public function getImageStringData($base64 = false)
313316
return null;
314317
}
315318

316-
// Read image binary data and convert to hex
319+
// Read image binary data and convert to hex/base64 string
317320
if ($this->sourceType == self::SOURCE_GD) {
318321
$imageResource = call_user_func($this->imageCreateFunc, $actualSource);
319322
ob_start();
@@ -335,6 +338,11 @@ public function getImageStringData($base64 = false)
335338
}
336339
}
337340

341+
// Delete temporary file if necessary
342+
if ($isTemp === true) {
343+
@unlink($actualSource);
344+
}
345+
338346
return $imageData;
339347
}
340348

src/PhpWord/Media.php

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -139,37 +139,53 @@ public static function countElements($container, $mediaType = null)
139139
* Get media elements
140140
*
141141
* @param string $container section|headerx|footerx|footnote|endnote
142-
* @param string $mediaType image|object|link
142+
* @param string $type image|object|link
143143
* @return array
144144
* @since 0.10.0
145145
*/
146-
public static function getElements($container, $mediaType = null)
146+
public static function getElements($container, $type = null)
147147
{
148-
$mediaElements = array();
148+
$elements = array();
149149

150150
// If header/footer, search for headerx and footerx where x is number
151151
if ($container == 'header' || $container == 'footer') {
152152
foreach (self::$elements as $key => $val) {
153153
if (substr($key, 0, 6) == $container) {
154-
$mediaElements[$key] = $val;
154+
$elements[$key] = $val;
155155
}
156156
}
157+
return $elements;
157158
} else {
158159
if (!array_key_exists($container, self::$elements)) {
159-
return $mediaElements;
160+
return $elements;
160161
}
161-
foreach (self::$elements[$container] as $mediaKey => $mediaData) {
162-
if (!is_null($mediaType)) {
163-
if ($mediaType == $mediaData['type']) {
164-
$mediaElements[$mediaKey] = $mediaData;
165-
}
166-
} else {
167-
$mediaElements[$mediaKey] = $mediaData;
162+
return self::getElementsByType($container, $type);
163+
}
164+
}
165+
166+
/**
167+
* Get elements by media type
168+
*
169+
* @param string $container section|footnote|endnote
170+
* @param string $type image|object|link
171+
* @return array
172+
* @since 0.11.0 Splitted from `getElements` to reduce complexity
173+
*/
174+
private static function getElementsByType($container, $type = null)
175+
{
176+
$elements = array();
177+
178+
foreach (self::$elements[$container] as $key => $data) {
179+
if ($type !== null) {
180+
if ($type == $data['type']) {
181+
$elements[$key] = $data;
168182
}
183+
} else {
184+
$elements[$key] = $data;
169185
}
170186
}
171187

172-
return $mediaElements;
188+
return $elements;
173189
}
174190

175191
/**

src/PhpWord/Reader/Word2007/AbstractPart.php

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -453,25 +453,41 @@ protected function readStyleDefs(XMLReader $xmlReader, \DOMElement $parentNode =
453453
$attribute = ($attribute === null) ? 'w:val' : $attribute;
454454
$attributeValue = $xmlReader->getAttribute($attribute, $node);
455455

456-
// Assign style value based on conversion model
457-
if ($method == self::READ_VALUE) {
458-
$styles[$styleProp] = $attributeValue;
459-
} elseif ($method == self::READ_SIZE) {
460-
$styles[$styleProp] = $attributeValue / 2;
461-
} elseif ($method == self::READ_TRUE) {
462-
$styles[$styleProp] = true;
463-
} elseif ($method == self::READ_FALSE) {
464-
$styles[$styleProp] = false;
465-
} elseif ($method == self::READ_EQUAL && $attributeValue == $expected) {
466-
$styles[$styleProp] = true;
456+
$styleValue = $this->readStyleDef($method, $attributeValue, $expected);
457+
if ($styleValue !== null) {
458+
$styles[$styleProp] = $styleValue;
467459
}
468460
}
469461
}
470462

471-
/** @var array $styles Type hint */
472463
return $styles;
473464
}
474465

466+
/**
467+
* Return style definition based on conversion method
468+
*
469+
* @param string $method
470+
* @param mixed $attributeValue
471+
* @param mixed $expected
472+
* @return mixed
473+
*/
474+
private function readStyleDef($method, $attributeValue, $expected)
475+
{
476+
$style = $attributeValue;
477+
478+
if ($method == self::READ_SIZE) {
479+
$style = $attributeValue / 2;
480+
} elseif ($method == self::READ_TRUE) {
481+
$style = true;
482+
} elseif ($method == self::READ_FALSE) {
483+
$style = false;
484+
} elseif ($method == self::READ_EQUAL && $attributeValue == $expected) {
485+
$style = true;
486+
}
487+
488+
return $style;
489+
}
490+
475491
/**
476492
* Returns the target of image, object, or link as stored in ::readMainRels
477493
*

src/PhpWord/Shared/Html.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ protected static function parseNode(
214214
*/
215215
case 'li':
216216
$cNodes = $node->childNodes;
217-
if (count($cNodes) > 0) {
217+
if ($cNodes->length > 0) {
218218
$text = '';
219219
foreach ($cNodes as $cNode) {
220220
if ($cNode->nodeName == '#text') {
@@ -240,7 +240,7 @@ protected static function parseNode(
240240
*/
241241
if ($node->nodeName != 'li') {
242242
$cNodes = $node->childNodes;
243-
if (count($cNodes) > 0) {
243+
if ($cNodes->length > 0) {
244244
foreach ($cNodes as $cNode) {
245245
self::parseNode($cNode, $newobject, $styles, $data);
246246
}

src/PhpWord/Writer/Word2007/Element/TextBreak.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,13 @@ public function write()
3737

3838
if (!$this->withoutP) {
3939
$hasStyle = $element->hasStyle();
40+
$this->writeOpeningWP();
4041
if ($hasStyle) {
41-
$this->writeOpeningWP();
4242
$xmlWriter->startElement('w:pPr');
4343
$this->writeFontStyle();
4444
$xmlWriter->endElement(); // w:pPr
45-
$this->writeClosingWP();
46-
} else {
47-
$xmlWriter->writeElement('w:p');
4845
}
46+
$this->writeClosingWP();
4947
} else {
5048
$xmlWriter->writeElement('w:br');
5149
}

src/PhpWord/Writer/Word2007/Part/Numbering.php

Lines changed: 56 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
/**
2626
* Word2007 numbering part writer: word/numbering.xml
27+
*
28+
* @since 0.10.0
2729
*/
2830
class Numbering extends AbstractPart
2931
{
@@ -97,12 +99,6 @@ public function write()
9799
*/
98100
private function writeLevel(XMLWriter $xmlWriter, NumberingLevel $level)
99101
{
100-
$tabPos = $level->getTabPos();
101-
$left = $level->getLeft();
102-
$hanging = $level->getHanging();
103-
$font = $level->getFont();
104-
$hint = $level->getHint();
105-
106102
$xmlWriter->startElement('w:lvl');
107103
$xmlWriter->writeAttribute('w:ilvl', $level->getLevel());
108104

@@ -124,48 +120,64 @@ private function writeLevel(XMLWriter $xmlWriter, NumberingLevel $level)
124120
}
125121
}
126122

127-
// Paragraph styles
128-
if (!is_null($tabPos) || !is_null($left) || !is_null($hanging)) {
129-
$xmlWriter->startElement('w:pPr');
130-
if (!is_null($tabPos)) {
131-
$xmlWriter->startElement('w:tabs');
132-
$xmlWriter->startElement('w:tab');
133-
$xmlWriter->writeAttribute('w:val', 'num');
134-
$xmlWriter->writeAttribute('w:pos', $tabPos);
135-
$xmlWriter->endElement(); // w:tab
136-
$xmlWriter->endElement(); // w:tabs
137-
}
138-
if (!is_null($left) || !is_null($hanging)) {
139-
$xmlWriter->startElement('w:ind');
140-
if (!is_null($left)) {
141-
$xmlWriter->writeAttribute('w:left', $left);
142-
}
143-
if (!is_null($hanging)) {
144-
$xmlWriter->writeAttribute('w:hanging', $hanging);
145-
}
146-
$xmlWriter->endElement(); // w:ind
147-
}
148-
$xmlWriter->endElement(); // w:pPr
149-
}
123+
// Paragraph & font styles
124+
$this->writeParagraph($xmlWriter, $level);
125+
$this->writeFont($xmlWriter, $level);
150126

151-
// Font styles
152-
if (!is_null($font) || !is_null($hint)) {
153-
$xmlWriter->startElement('w:rPr');
154-
$xmlWriter->startElement('w:rFonts');
155-
if (!is_null($font)) {
156-
$xmlWriter->writeAttribute('w:ascii', $font);
157-
$xmlWriter->writeAttribute('w:hAnsi', $font);
158-
$xmlWriter->writeAttribute('w:cs', $font);
159-
}
160-
if (!is_null($hint)) {
161-
$xmlWriter->writeAttribute('w:hint', $hint);
162-
}
163-
$xmlWriter->endElement(); // w:rFonts
164-
$xmlWriter->endElement(); // w:rPr
165-
}
166127
$xmlWriter->endElement(); // w:lvl
167128
}
168129

130+
/**
131+
* Write level paragraph
132+
*
133+
* @since 0.11.0
134+
* @todo Use paragraph style writer
135+
*/
136+
private function writeParagraph(XMLWriter $xmlWriter, NumberingLevel $level)
137+
{
138+
$tabPos = $level->getTabPos();
139+
$left = $level->getLeft();
140+
$hanging = $level->getHanging();
141+
142+
$xmlWriter->startElement('w:pPr');
143+
144+
$xmlWriter->startElement('w:tabs');
145+
$xmlWriter->startElement('w:tab');
146+
$xmlWriter->writeAttribute('w:val', 'num');
147+
$xmlWriter->writeAttributeIf($tabPos !== null, 'w:pos', $tabPos);
148+
$xmlWriter->writeAttribute('w:pos', $tabPos);
149+
$xmlWriter->endElement(); // w:tab
150+
$xmlWriter->endElement(); // w:tabs
151+
152+
$xmlWriter->startElement('w:ind');
153+
$xmlWriter->writeAttributeIf($left !== null, 'w:left', $left);
154+
$xmlWriter->writeAttributeIf($hanging !== null, 'w:hanging', $hanging);
155+
$xmlWriter->endElement(); // w:ind
156+
157+
$xmlWriter->endElement(); // w:pPr
158+
}
159+
160+
/**
161+
* Write level font
162+
*
163+
* @since 0.11.0
164+
* @todo Use font style writer
165+
*/
166+
private function writeFont(XMLWriter $xmlWriter, NumberingLevel $level)
167+
{
168+
$font = $level->getFont();
169+
$hint = $level->getHint();
170+
171+
$xmlWriter->startElement('w:rPr');
172+
$xmlWriter->startElement('w:rFonts');
173+
$xmlWriter->writeAttributeIf($font !== null, 'w:ascii', $font);
174+
$xmlWriter->writeAttributeIf($font !== null, 'w:hAnsi', $font);
175+
$xmlWriter->writeAttributeIf($font !== null, 'w:cs', $font);
176+
$xmlWriter->writeAttributeIf($hint !== null, 'w:hint', $hint);
177+
$xmlWriter->endElement(); // w:rFonts
178+
$xmlWriter->endElement(); // w:rPr
179+
}
180+
169181
/**
170182
* Get random hexadecimal number value
171183
*

0 commit comments

Comments
 (0)