QA: Reduce some complexities: https://scrutinizer-ci.com/g/PHPOffice/PHPWord/code-structure/develop?elementType=operation
This commit is contained in:
parent
5ff47f44e9
commit
1e9a498ca2
|
|
@ -56,38 +56,24 @@ abstract class AbstractContainer extends AbstractElement
|
|||
|
||||
// Get arguments
|
||||
$args = func_get_args();
|
||||
$argsCount = func_num_args();
|
||||
$withoutP = in_array($this->container, array('TextRun', 'Footnote', 'Endnote', 'ListItemRun'));
|
||||
if ($withoutP && ($elementName == 'Text' || $elementName == 'PreserveText')) {
|
||||
$args[3] = null;
|
||||
$args[3] = null; // Remove paragraph style for texts in textrun
|
||||
}
|
||||
|
||||
// Create element dynamically
|
||||
|
||||
// Create element using reflection
|
||||
$reflection = new \ReflectionClass($elementClass);
|
||||
$elementArgs = $args;
|
||||
array_shift($elementArgs); // Shift an element off the beginning of array: the $elementName
|
||||
/** @var \PhpOffice\PhpWord\Element\AbstractElement $element Type hint */
|
||||
if ($argsCount == 2) { // TextRun, TextBox, Table, Footnote, Endnote
|
||||
$element = new $elementClass($args[1]);
|
||||
} elseif ($argsCount == 3) { // Object, TextBreak, Title
|
||||
$element = new $elementClass($args[1], $args[2]);
|
||||
} elseif ($argsCount == 4) { // PreserveText, Text, Image
|
||||
$element = new $elementClass($args[1], $args[2], $args[3]);
|
||||
} elseif ($argsCount == 5) { // CheckBox, Link, ListItemRun, TOC
|
||||
$element = new $elementClass($args[1], $args[2], $args[3], $args[4]);
|
||||
} elseif ($argsCount == 6) { // ListItem
|
||||
$element = new $elementClass($args[1], $args[2], $args[3], $args[4], $args[5]);
|
||||
} else { // Page Break
|
||||
$element = new $elementClass();
|
||||
}
|
||||
$element = $reflection->newInstanceArgs($elementArgs);
|
||||
|
||||
// Set relation Id for media collection
|
||||
$mediaContainer = $this->getMediaContainer();
|
||||
if (in_array($elementName, array('Link', 'Image', 'Object'))) {
|
||||
if ($elementName == 'Image') {
|
||||
/** @var \PhpOffice\PhpWord\Element\Image $element Type hint */
|
||||
$rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1], $element);
|
||||
} else {
|
||||
$rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1]);
|
||||
}
|
||||
/** @var \PhpOffice\PhpWord\Element\Image $element Type hint */
|
||||
$image = ($elementName == 'Image') ? $element : null;
|
||||
$rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1], $image);
|
||||
$element->setRelationId($rId);
|
||||
}
|
||||
if ($elementName == 'Object') {
|
||||
|
|
|
|||
|
|
@ -284,6 +284,7 @@ class Image extends AbstractElement
|
|||
*
|
||||
* @param bool $base64
|
||||
* @return string|null
|
||||
* @since 0.11.0
|
||||
*/
|
||||
public function getImageStringData($base64 = false)
|
||||
{
|
||||
|
|
@ -291,6 +292,7 @@ class Image extends AbstractElement
|
|||
$actualSource = null;
|
||||
$imageBinary = null;
|
||||
$imageData = null;
|
||||
$isTemp = false;
|
||||
|
||||
// Get actual source from archive image or other source
|
||||
// Return null if not found
|
||||
|
|
@ -301,6 +303,7 @@ class Image extends AbstractElement
|
|||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipFilename) !== false) {
|
||||
if ($zip->locateName($imageFilename)) {
|
||||
$isTemp = true;
|
||||
$zip->extractTo(sys_get_temp_dir(), $imageFilename);
|
||||
$actualSource = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $imageFilename;
|
||||
}
|
||||
|
|
@ -313,7 +316,7 @@ class Image extends AbstractElement
|
|||
return null;
|
||||
}
|
||||
|
||||
// Read image binary data and convert to hex
|
||||
// Read image binary data and convert to hex/base64 string
|
||||
if ($this->sourceType == self::SOURCE_GD) {
|
||||
$imageResource = call_user_func($this->imageCreateFunc, $actualSource);
|
||||
ob_start();
|
||||
|
|
@ -335,6 +338,11 @@ class Image extends AbstractElement
|
|||
}
|
||||
}
|
||||
|
||||
// Delete temporary file if necessary
|
||||
if ($isTemp === true) {
|
||||
@unlink($actualSource);
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -139,37 +139,53 @@ class Media
|
|||
* Get media elements
|
||||
*
|
||||
* @param string $container section|headerx|footerx|footnote|endnote
|
||||
* @param string $mediaType image|object|link
|
||||
* @param string $type image|object|link
|
||||
* @return array
|
||||
* @since 0.10.0
|
||||
*/
|
||||
public static function getElements($container, $mediaType = null)
|
||||
public static function getElements($container, $type = null)
|
||||
{
|
||||
$mediaElements = array();
|
||||
$elements = array();
|
||||
|
||||
// If header/footer, search for headerx and footerx where x is number
|
||||
if ($container == 'header' || $container == 'footer') {
|
||||
foreach (self::$elements as $key => $val) {
|
||||
if (substr($key, 0, 6) == $container) {
|
||||
$mediaElements[$key] = $val;
|
||||
$elements[$key] = $val;
|
||||
}
|
||||
}
|
||||
return $elements;
|
||||
} else {
|
||||
if (!array_key_exists($container, self::$elements)) {
|
||||
return $mediaElements;
|
||||
return $elements;
|
||||
}
|
||||
foreach (self::$elements[$container] as $mediaKey => $mediaData) {
|
||||
if (!is_null($mediaType)) {
|
||||
if ($mediaType == $mediaData['type']) {
|
||||
$mediaElements[$mediaKey] = $mediaData;
|
||||
}
|
||||
} else {
|
||||
$mediaElements[$mediaKey] = $mediaData;
|
||||
return self::getElementsByType($container, $type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get elements by media type
|
||||
*
|
||||
* @param string $container section|footnote|endnote
|
||||
* @param string $type image|object|link
|
||||
* @return array
|
||||
* @since 0.11.0 Splitted from `getElements` to reduce complexity
|
||||
*/
|
||||
private static function getElementsByType($container, $type = null)
|
||||
{
|
||||
$elements = array();
|
||||
|
||||
foreach (self::$elements[$container] as $key => $data) {
|
||||
if ($type !== null) {
|
||||
if ($type == $data['type']) {
|
||||
$elements[$key] = $data;
|
||||
}
|
||||
} else {
|
||||
$elements[$key] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
return $mediaElements;
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -453,25 +453,41 @@ abstract class AbstractPart
|
|||
$attribute = ($attribute === null) ? 'w:val' : $attribute;
|
||||
$attributeValue = $xmlReader->getAttribute($attribute, $node);
|
||||
|
||||
// Assign style value based on conversion model
|
||||
if ($method == self::READ_VALUE) {
|
||||
$styles[$styleProp] = $attributeValue;
|
||||
} elseif ($method == self::READ_SIZE) {
|
||||
$styles[$styleProp] = $attributeValue / 2;
|
||||
} elseif ($method == self::READ_TRUE) {
|
||||
$styles[$styleProp] = true;
|
||||
} elseif ($method == self::READ_FALSE) {
|
||||
$styles[$styleProp] = false;
|
||||
} elseif ($method == self::READ_EQUAL && $attributeValue == $expected) {
|
||||
$styles[$styleProp] = true;
|
||||
$styleValue = $this->readStyleDef($method, $attributeValue, $expected);
|
||||
if ($styleValue !== null) {
|
||||
$styles[$styleProp] = $styleValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @var array $styles Type hint */
|
||||
return $styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return style definition based on conversion method
|
||||
*
|
||||
* @param string $method
|
||||
* @param mixed $attributeValue
|
||||
* @param mixed $expected
|
||||
* @return mixed
|
||||
*/
|
||||
private function readStyleDef($method, $attributeValue, $expected)
|
||||
{
|
||||
$style = $attributeValue;
|
||||
|
||||
if ($method == self::READ_SIZE) {
|
||||
$style = $attributeValue / 2;
|
||||
} elseif ($method == self::READ_TRUE) {
|
||||
$style = true;
|
||||
} elseif ($method == self::READ_FALSE) {
|
||||
$style = false;
|
||||
} elseif ($method == self::READ_EQUAL && $attributeValue == $expected) {
|
||||
$style = true;
|
||||
}
|
||||
|
||||
return $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the target of image, object, or link as stored in ::readMainRels
|
||||
*
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ class Html
|
|||
*/
|
||||
case 'li':
|
||||
$cNodes = $node->childNodes;
|
||||
if (count($cNodes) > 0) {
|
||||
if ($cNodes->length > 0) {
|
||||
$text = '';
|
||||
foreach ($cNodes as $cNode) {
|
||||
if ($cNode->nodeName == '#text') {
|
||||
|
|
@ -240,7 +240,7 @@ class Html
|
|||
*/
|
||||
if ($node->nodeName != 'li') {
|
||||
$cNodes = $node->childNodes;
|
||||
if (count($cNodes) > 0) {
|
||||
if ($cNodes->length > 0) {
|
||||
foreach ($cNodes as $cNode) {
|
||||
self::parseNode($cNode, $newobject, $styles, $data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,15 +37,13 @@ class TextBreak extends Text
|
|||
|
||||
if (!$this->withoutP) {
|
||||
$hasStyle = $element->hasStyle();
|
||||
$this->writeOpeningWP();
|
||||
if ($hasStyle) {
|
||||
$this->writeOpeningWP();
|
||||
$xmlWriter->startElement('w:pPr');
|
||||
$this->writeFontStyle();
|
||||
$xmlWriter->endElement(); // w:pPr
|
||||
$this->writeClosingWP();
|
||||
} else {
|
||||
$xmlWriter->writeElement('w:p');
|
||||
}
|
||||
$this->writeClosingWP();
|
||||
} else {
|
||||
$xmlWriter->writeElement('w:br');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ use PhpOffice\PhpWord\Style\NumberingLevel;
|
|||
|
||||
/**
|
||||
* Word2007 numbering part writer: word/numbering.xml
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
class Numbering extends AbstractPart
|
||||
{
|
||||
|
|
@ -97,12 +99,6 @@ class Numbering extends AbstractPart
|
|||
*/
|
||||
private function writeLevel(XMLWriter $xmlWriter, NumberingLevel $level)
|
||||
{
|
||||
$tabPos = $level->getTabPos();
|
||||
$left = $level->getLeft();
|
||||
$hanging = $level->getHanging();
|
||||
$font = $level->getFont();
|
||||
$hint = $level->getHint();
|
||||
|
||||
$xmlWriter->startElement('w:lvl');
|
||||
$xmlWriter->writeAttribute('w:ilvl', $level->getLevel());
|
||||
|
||||
|
|
@ -124,48 +120,64 @@ class Numbering extends AbstractPart
|
|||
}
|
||||
}
|
||||
|
||||
// Paragraph styles
|
||||
if (!is_null($tabPos) || !is_null($left) || !is_null($hanging)) {
|
||||
$xmlWriter->startElement('w:pPr');
|
||||
if (!is_null($tabPos)) {
|
||||
$xmlWriter->startElement('w:tabs');
|
||||
$xmlWriter->startElement('w:tab');
|
||||
$xmlWriter->writeAttribute('w:val', 'num');
|
||||
$xmlWriter->writeAttribute('w:pos', $tabPos);
|
||||
$xmlWriter->endElement(); // w:tab
|
||||
$xmlWriter->endElement(); // w:tabs
|
||||
}
|
||||
if (!is_null($left) || !is_null($hanging)) {
|
||||
$xmlWriter->startElement('w:ind');
|
||||
if (!is_null($left)) {
|
||||
$xmlWriter->writeAttribute('w:left', $left);
|
||||
}
|
||||
if (!is_null($hanging)) {
|
||||
$xmlWriter->writeAttribute('w:hanging', $hanging);
|
||||
}
|
||||
$xmlWriter->endElement(); // w:ind
|
||||
}
|
||||
$xmlWriter->endElement(); // w:pPr
|
||||
}
|
||||
// Paragraph & font styles
|
||||
$this->writeParagraph($xmlWriter, $level);
|
||||
$this->writeFont($xmlWriter, $level);
|
||||
|
||||
// Font styles
|
||||
if (!is_null($font) || !is_null($hint)) {
|
||||
$xmlWriter->startElement('w:rPr');
|
||||
$xmlWriter->startElement('w:rFonts');
|
||||
if (!is_null($font)) {
|
||||
$xmlWriter->writeAttribute('w:ascii', $font);
|
||||
$xmlWriter->writeAttribute('w:hAnsi', $font);
|
||||
$xmlWriter->writeAttribute('w:cs', $font);
|
||||
}
|
||||
if (!is_null($hint)) {
|
||||
$xmlWriter->writeAttribute('w:hint', $hint);
|
||||
}
|
||||
$xmlWriter->endElement(); // w:rFonts
|
||||
$xmlWriter->endElement(); // w:rPr
|
||||
}
|
||||
$xmlWriter->endElement(); // w:lvl
|
||||
}
|
||||
|
||||
/**
|
||||
* Write level paragraph
|
||||
*
|
||||
* @since 0.11.0
|
||||
* @todo Use paragraph style writer
|
||||
*/
|
||||
private function writeParagraph(XMLWriter $xmlWriter, NumberingLevel $level)
|
||||
{
|
||||
$tabPos = $level->getTabPos();
|
||||
$left = $level->getLeft();
|
||||
$hanging = $level->getHanging();
|
||||
|
||||
$xmlWriter->startElement('w:pPr');
|
||||
|
||||
$xmlWriter->startElement('w:tabs');
|
||||
$xmlWriter->startElement('w:tab');
|
||||
$xmlWriter->writeAttribute('w:val', 'num');
|
||||
$xmlWriter->writeAttributeIf($tabPos !== null, 'w:pos', $tabPos);
|
||||
$xmlWriter->writeAttribute('w:pos', $tabPos);
|
||||
$xmlWriter->endElement(); // w:tab
|
||||
$xmlWriter->endElement(); // w:tabs
|
||||
|
||||
$xmlWriter->startElement('w:ind');
|
||||
$xmlWriter->writeAttributeIf($left !== null, 'w:left', $left);
|
||||
$xmlWriter->writeAttributeIf($hanging !== null, 'w:hanging', $hanging);
|
||||
$xmlWriter->endElement(); // w:ind
|
||||
|
||||
$xmlWriter->endElement(); // w:pPr
|
||||
}
|
||||
|
||||
/**
|
||||
* Write level font
|
||||
*
|
||||
* @since 0.11.0
|
||||
* @todo Use font style writer
|
||||
*/
|
||||
private function writeFont(XMLWriter $xmlWriter, NumberingLevel $level)
|
||||
{
|
||||
$font = $level->getFont();
|
||||
$hint = $level->getHint();
|
||||
|
||||
$xmlWriter->startElement('w:rPr');
|
||||
$xmlWriter->startElement('w:rFonts');
|
||||
$xmlWriter->writeAttributeIf($font !== null, 'w:ascii', $font);
|
||||
$xmlWriter->writeAttributeIf($font !== null, 'w:hAnsi', $font);
|
||||
$xmlWriter->writeAttributeIf($font !== null, 'w:cs', $font);
|
||||
$xmlWriter->writeAttributeIf($hint !== null, 'w:hint', $hint);
|
||||
$xmlWriter->endElement(); // w:rFonts
|
||||
$xmlWriter->endElement(); // w:rPr
|
||||
}
|
||||
|
||||
/**
|
||||
* Get random hexadecimal number value
|
||||
*
|
||||
|
|
|
|||
|
|
@ -50,43 +50,51 @@ class Rels extends AbstractPart
|
|||
* Write relationships
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
|
||||
* @param null|array $xmlRels
|
||||
* @param null|array $mediaRels
|
||||
* @param integer $relId
|
||||
* @param array $xmlRels
|
||||
* @param array $mediaRels
|
||||
* @param int $relId
|
||||
*/
|
||||
protected function writeRels(XMLWriter $xmlWriter, $xmlRels = null, $mediaRels = null, $relId = 1)
|
||||
protected function writeRels(XMLWriter $xmlWriter, $xmlRels = array(), $mediaRels = array(), $relId = 1)
|
||||
{
|
||||
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes');
|
||||
$xmlWriter->startElement('Relationships');
|
||||
$xmlWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
|
||||
|
||||
// XML files relationships
|
||||
if (is_array($xmlRels)) {
|
||||
foreach ($xmlRels as $target => $type) {
|
||||
$this->writeRel($xmlWriter, $relId++, $type, $target);
|
||||
}
|
||||
foreach ($xmlRels as $target => $type) {
|
||||
$this->writeRel($xmlWriter, $relId++, $type, $target);
|
||||
}
|
||||
|
||||
// Media relationships
|
||||
if (is_array($mediaRels)) {
|
||||
$typePrefix = 'officeDocument/2006/relationships/';
|
||||
$typeMapping = array('image' => 'image', 'object' => 'oleObject', 'link' => 'hyperlink');
|
||||
$targetPaths = array('image' => 'media/', 'object' => 'embeddings/');
|
||||
|
||||
foreach ($mediaRels as $mediaRel) {
|
||||
$mediaType = $mediaRel['type'];
|
||||
$type = array_key_exists($mediaType, $typeMapping) ? $typeMapping[$mediaType] : $mediaType;
|
||||
$target = array_key_exists($mediaType, $targetPaths) ? $targetPaths[$mediaType] : '';
|
||||
$target .= $mediaRel['target'];
|
||||
$targetMode = ($type == 'hyperlink') ? 'External' : '';
|
||||
|
||||
$this->writeRel($xmlWriter, $relId++, $typePrefix . $type, $target, $targetMode);
|
||||
}
|
||||
foreach ($mediaRels as $mediaRel) {
|
||||
$this->writeMediaRel($xmlWriter, $relId++, $mediaRel);
|
||||
}
|
||||
|
||||
$xmlWriter->endElement(); // Relationships
|
||||
}
|
||||
|
||||
/**
|
||||
* Write media relationships
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
|
||||
* @param int $relId
|
||||
* @param array $mediaRel
|
||||
*/
|
||||
private function writeMediaRel(XMLWriter $xmlWriter, $relId, $mediaRel)
|
||||
{
|
||||
$typePrefix = 'officeDocument/2006/relationships/';
|
||||
$typeMapping = array('image' => 'image', 'object' => 'oleObject', 'link' => 'hyperlink');
|
||||
$targetMapping = array('image' => 'media/', 'object' => 'embeddings/');
|
||||
|
||||
$mediaType = $mediaRel['type'];
|
||||
$type = array_key_exists($mediaType, $typeMapping) ? $typeMapping[$mediaType] : $mediaType;
|
||||
$targetPrefix = array_key_exists($mediaType, $targetMapping) ? $targetMapping[$mediaType] : '';
|
||||
$target = $mediaRel['target'];
|
||||
$targetMode = ($type == 'hyperlink') ? 'External' : '';
|
||||
|
||||
$this->writeRel($xmlWriter, $relId, $typePrefix . $type, $targetPrefix . $target, $targetMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write individual rels entry
|
||||
*
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class RelsPart extends Rels
|
|||
public function write()
|
||||
{
|
||||
$xmlWriter = $this->getXmlWriter();
|
||||
$this->writeRels($xmlWriter, null, $this->media);
|
||||
$this->writeRels($xmlWriter, array(), $this->media);
|
||||
|
||||
return $xmlWriter->getData();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue