1
This commit is contained in:
@@ -46,7 +46,7 @@ abstract class AbstractCollection
|
||||
*
|
||||
* @param int $index
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Element\AbstractContainer
|
||||
* @return ?\PhpOffice\PhpWord\Element\AbstractContainer
|
||||
*/
|
||||
public function getItem($index)
|
||||
{
|
||||
@@ -61,7 +61,7 @@ abstract class AbstractCollection
|
||||
* Set item.
|
||||
*
|
||||
* @param int $index
|
||||
* @param \PhpOffice\PhpWord\Element\AbstractContainer $item
|
||||
* @param ?\PhpOffice\PhpWord\Element\AbstractContainer $item
|
||||
*/
|
||||
public function setItem($index, $item): void
|
||||
{
|
||||
@@ -79,7 +79,7 @@ abstract class AbstractCollection
|
||||
*/
|
||||
public function addItem($item)
|
||||
{
|
||||
$index = $this->countItems() + 1;
|
||||
$index = $this->countItems();
|
||||
$this->items[$index] = $item;
|
||||
|
||||
return $index;
|
||||
|
||||
@@ -72,7 +72,7 @@ final class TrackChangesView
|
||||
/**
|
||||
* Set Display Visual Indicator Of Markup Area.
|
||||
*
|
||||
* @param bool $markup
|
||||
* @param ?bool $markup
|
||||
* Set to true to show markup
|
||||
*/
|
||||
public function setMarkup($markup): void
|
||||
@@ -93,7 +93,7 @@ final class TrackChangesView
|
||||
/**
|
||||
* Set Display Comments.
|
||||
*
|
||||
* @param bool $comments
|
||||
* @param ?bool $comments
|
||||
* Set to true to show comments
|
||||
*/
|
||||
public function setComments($comments): void
|
||||
@@ -114,7 +114,7 @@ final class TrackChangesView
|
||||
/**
|
||||
* Set Display Content Revisions.
|
||||
*
|
||||
* @param bool $insDel
|
||||
* @param ?bool $insDel
|
||||
* Set to true to show content revisions
|
||||
*/
|
||||
public function setInsDel($insDel): void
|
||||
@@ -156,7 +156,7 @@ final class TrackChangesView
|
||||
/**
|
||||
* Set Display Ink Annotations.
|
||||
*
|
||||
* @param bool $inkAnnotations
|
||||
* @param ?bool $inkAnnotations
|
||||
* Set to true to show ink annotations
|
||||
*/
|
||||
public function setInkAnnotations($inkAnnotations): void
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
namespace PhpOffice\PhpWord\Element;
|
||||
|
||||
use BadMethodCallException;
|
||||
use PhpOffice\Math\Math;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
@@ -34,7 +35,7 @@ use ReflectionClass;
|
||||
* @method Footnote addFootnote(mixed $pStyle = null)
|
||||
* @method Endnote addEndnote(mixed $pStyle = null)
|
||||
* @method CheckBox addCheckBox(string $name, $text, mixed $fStyle = null, mixed $pStyle = null)
|
||||
* @method Title addTitle(mixed $text, int $depth = 1)
|
||||
* @method Title addTitle(mixed $text, int $depth = 1, int $pageNumber = null)
|
||||
* @method TOC addTOC(mixed $fontStyle = null, mixed $tocStyle = null, int $minDepth = 1, int $maxDepth = 9)
|
||||
* @method PageBreak addPageBreak()
|
||||
* @method Table addTable(mixed $style = null)
|
||||
@@ -47,6 +48,7 @@ use ReflectionClass;
|
||||
* @method Chart addChart(string $type, array $categories, array $values, array $style = null, $seriesName = null)
|
||||
* @method FormField addFormField(string $type, mixed $fStyle = null, mixed $pStyle = null)
|
||||
* @method SDT addSDT(string $type)
|
||||
* @method Formula addFormula(Math $math)
|
||||
* @method \PhpOffice\PhpWord\Element\OLEObject addObject(string $source, mixed $style = null) deprecated, use addOLEObject instead
|
||||
*
|
||||
* @since 0.10.0
|
||||
@@ -88,6 +90,7 @@ abstract class AbstractContainer extends AbstractElement
|
||||
'Footnote', 'Endnote', 'CheckBox', 'TextBox', 'Field',
|
||||
'Line', 'Shape', 'Title', 'TOC', 'PageBreak',
|
||||
'Chart', 'FormField', 'SDT', 'Comment',
|
||||
'Formula',
|
||||
];
|
||||
$functions = [];
|
||||
foreach ($elements as $element) {
|
||||
|
||||
@@ -32,7 +32,7 @@ abstract class AbstractElement
|
||||
/**
|
||||
* PhpWord object.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\PhpWord
|
||||
* @var ?\PhpOffice\PhpWord\PhpWord
|
||||
*/
|
||||
protected $phpWord;
|
||||
|
||||
@@ -147,7 +147,7 @@ abstract class AbstractElement
|
||||
/**
|
||||
* Get PhpWord.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\PhpWord
|
||||
* @return ?\PhpOffice\PhpWord\PhpWord
|
||||
*/
|
||||
public function getPhpWord()
|
||||
{
|
||||
@@ -156,8 +156,6 @@ abstract class AbstractElement
|
||||
|
||||
/**
|
||||
* Set PhpWord as reference.
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\PhpWord $phpWord
|
||||
*/
|
||||
public function setPhpWord(?PhpWord $phpWord = null): void
|
||||
{
|
||||
@@ -347,8 +345,6 @@ abstract class AbstractElement
|
||||
* Set parent container.
|
||||
*
|
||||
* Passed parameter should be a container, except for Table (contain Row) and Row (contain Cell)
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Element\AbstractElement $container
|
||||
*/
|
||||
public function setParentContainer(self $container): void
|
||||
{
|
||||
@@ -432,7 +428,7 @@ abstract class AbstractElement
|
||||
* Set new style value.
|
||||
*
|
||||
* @param mixed $styleObject Style object
|
||||
* @param mixed $styleValue Style value
|
||||
* @param null|array|\PhpOffice\PhpWord\Style|string $styleValue Style value
|
||||
* @param bool $returnObject Always return object
|
||||
*
|
||||
* @return mixed
|
||||
|
||||
@@ -32,21 +32,21 @@ class Cell extends AbstractContainer
|
||||
/**
|
||||
* Cell width.
|
||||
*
|
||||
* @var int
|
||||
* @var ?int
|
||||
*/
|
||||
private $width;
|
||||
|
||||
/**
|
||||
* Cell style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Cell
|
||||
* @var ?\PhpOffice\PhpWord\Style\Cell
|
||||
*/
|
||||
private $style;
|
||||
|
||||
/**
|
||||
* Create new instance.
|
||||
*
|
||||
* @param int $width
|
||||
* @param null|int $width
|
||||
* @param array|\PhpOffice\PhpWord\Style\Cell $style
|
||||
*/
|
||||
public function __construct($width = null, $style = null)
|
||||
@@ -58,7 +58,7 @@ class Cell extends AbstractContainer
|
||||
/**
|
||||
* Get cell style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Cell
|
||||
* @return ?\PhpOffice\PhpWord\Style\Cell
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
@@ -68,7 +68,7 @@ class Cell extends AbstractContainer
|
||||
/**
|
||||
* Get cell width.
|
||||
*
|
||||
* @return int
|
||||
* @return ?int
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ class Chart extends AbstractElement
|
||||
/**
|
||||
* Chart style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Chart
|
||||
* @var ?\PhpOffice\PhpWord\Style\Chart
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -120,7 +120,7 @@ class Chart extends AbstractElement
|
||||
/**
|
||||
* Get chart style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Chart
|
||||
* @return ?\PhpOffice\PhpWord\Style\Chart
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
|
||||
@@ -79,8 +79,6 @@ class Comment extends TrackChange
|
||||
|
||||
/**
|
||||
* Sets the element where this comment starts.
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Element\AbstractElement $value
|
||||
*/
|
||||
public function setStartElement(AbstractElement $value): void
|
||||
{
|
||||
@@ -102,8 +100,6 @@ class Comment extends TrackChange
|
||||
|
||||
/**
|
||||
* Sets the element where this comment ends.
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Element\AbstractElement $value
|
||||
*/
|
||||
public function setEndElement(AbstractElement $value): void
|
||||
{
|
||||
|
||||
@@ -85,6 +85,12 @@ class Field extends AbstractElement
|
||||
'properties' => ['StyleIdentifier' => ''],
|
||||
'options' => ['PreserveFormat'],
|
||||
],
|
||||
'FILENAME' => [
|
||||
'properties' => [
|
||||
'format' => ['Upper', 'Lower', 'FirstCap', 'Caps'],
|
||||
],
|
||||
'options' => ['Path', 'PreserveFormat'],
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -268,7 +274,7 @@ class Field extends AbstractElement
|
||||
/**
|
||||
* Set Field text.
|
||||
*
|
||||
* @param string|TextRun $text
|
||||
* @param null|string|TextRun $text
|
||||
*
|
||||
* @return null|string|TextRun
|
||||
*/
|
||||
|
||||
@@ -29,7 +29,7 @@ class Footnote extends AbstractContainer
|
||||
/**
|
||||
* Paragraph style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Paragraph|string
|
||||
* @var null|\PhpOffice\PhpWord\Style\Paragraph|string
|
||||
*/
|
||||
protected $paragraphStyle;
|
||||
|
||||
@@ -54,7 +54,7 @@ class Footnote extends AbstractContainer
|
||||
/**
|
||||
* Get paragraph style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Paragraph|string
|
||||
* @return null|\PhpOffice\PhpWord\Style\Paragraph|string
|
||||
*/
|
||||
public function getParagraphStyle()
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ class FormField extends Text
|
||||
/**
|
||||
* Form field name.
|
||||
*
|
||||
* @var bool|int|string
|
||||
* @var ?string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
@@ -53,7 +53,7 @@ class FormField extends Text
|
||||
/**
|
||||
* Value.
|
||||
*
|
||||
* @var bool|int|string
|
||||
* @var null|bool|int|string
|
||||
*/
|
||||
private $value;
|
||||
|
||||
@@ -105,7 +105,7 @@ class FormField extends Text
|
||||
/**
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
* @return ?string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
@@ -115,7 +115,7 @@ class FormField extends Text
|
||||
/**
|
||||
* Set name.
|
||||
*
|
||||
* @param bool|int|string $value
|
||||
* @param ?string $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
@@ -153,7 +153,7 @@ class FormField extends Text
|
||||
/**
|
||||
* Get value.
|
||||
*
|
||||
* @return bool|int|string
|
||||
* @return null|bool|int|string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
@@ -163,7 +163,7 @@ class FormField extends Text
|
||||
/**
|
||||
* Set value.
|
||||
*
|
||||
* @param bool|int|string $value
|
||||
* @param null|bool|int|string $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
|
||||
53
vendor/phpoffice/phpword/src/PhpWord/Element/Formula.php
vendored
Normal file
53
vendor/phpoffice/phpword/src/PhpWord/Element/Formula.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
*
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpWord\Element;
|
||||
|
||||
use PhpOffice\Math\Math;
|
||||
|
||||
/**
|
||||
* Formula element.
|
||||
*/
|
||||
class Formula extends AbstractElement
|
||||
{
|
||||
/**
|
||||
* @var Math
|
||||
*/
|
||||
protected $math;
|
||||
|
||||
/**
|
||||
* Create a new Formula Element.
|
||||
*/
|
||||
public function __construct(Math $math)
|
||||
{
|
||||
$this->setMath($math);
|
||||
}
|
||||
|
||||
public function setMath(Math $math): self
|
||||
{
|
||||
$this->math = $math;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMath(): Math
|
||||
{
|
||||
return $this->math;
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ class Image extends AbstractElement
|
||||
/**
|
||||
* Image style.
|
||||
*
|
||||
* @var ImageStyle
|
||||
* @var ?ImageStyle
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -89,7 +89,7 @@ class Image extends AbstractElement
|
||||
/**
|
||||
* Image function.
|
||||
*
|
||||
* @var string
|
||||
* @var null|callable(resource): void
|
||||
*/
|
||||
private $imageFunc;
|
||||
|
||||
@@ -100,6 +100,16 @@ class Image extends AbstractElement
|
||||
*/
|
||||
private $imageExtension;
|
||||
|
||||
/**
|
||||
* Image quality.
|
||||
*
|
||||
* Functions imagepng() and imagejpeg() have an optional parameter for
|
||||
* quality.
|
||||
*
|
||||
* @var null|int
|
||||
*/
|
||||
private $imageQuality;
|
||||
|
||||
/**
|
||||
* Is memory image.
|
||||
*
|
||||
@@ -149,7 +159,7 @@ class Image extends AbstractElement
|
||||
/**
|
||||
* Get Image style.
|
||||
*
|
||||
* @return ImageStyle
|
||||
* @return ?ImageStyle
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
@@ -249,13 +259,21 @@ class Image extends AbstractElement
|
||||
/**
|
||||
* Get image function.
|
||||
*
|
||||
* @return string
|
||||
* @return null|callable(resource): void
|
||||
*/
|
||||
public function getImageFunction()
|
||||
public function getImageFunction(): ?callable
|
||||
{
|
||||
return $this->imageFunc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image quality.
|
||||
*/
|
||||
public function getImageQuality(): ?int
|
||||
{
|
||||
return $this->imageQuality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image extension.
|
||||
*
|
||||
@@ -317,20 +335,13 @@ class Image extends AbstractElement
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image string data.
|
||||
*
|
||||
* @param bool $base64
|
||||
*
|
||||
* @return null|string
|
||||
*
|
||||
* @since 0.11.0
|
||||
* Get image string.
|
||||
*/
|
||||
public function getImageStringData($base64 = false)
|
||||
public function getImageString(): ?string
|
||||
{
|
||||
$source = $this->source;
|
||||
$actualSource = null;
|
||||
$imageBinary = null;
|
||||
$imageData = null;
|
||||
$isTemp = false;
|
||||
|
||||
// Get actual source from archive image or other source
|
||||
@@ -367,7 +378,8 @@ class Image extends AbstractElement
|
||||
imagesavealpha($imageResource, true);
|
||||
}
|
||||
ob_start();
|
||||
call_user_func($this->imageFunc, $imageResource);
|
||||
$callback = $this->imageFunc;
|
||||
$callback($imageResource);
|
||||
$imageBinary = ob_get_contents();
|
||||
ob_end_clean();
|
||||
} elseif ($this->sourceType == self::SOURCE_STRING) {
|
||||
@@ -379,20 +391,36 @@ class Image extends AbstractElement
|
||||
fclose($fileHandle);
|
||||
}
|
||||
}
|
||||
if ($imageBinary !== null) {
|
||||
if ($base64) {
|
||||
$imageData = chunk_split(base64_encode($imageBinary));
|
||||
} else {
|
||||
$imageData = chunk_split(bin2hex($imageBinary));
|
||||
}
|
||||
}
|
||||
|
||||
// Delete temporary file if necessary
|
||||
if ($isTemp === true) {
|
||||
@unlink($actualSource);
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
return $imageBinary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image string data.
|
||||
*
|
||||
* @param bool $base64
|
||||
*
|
||||
* @return null|string
|
||||
*
|
||||
* @since 0.11.0
|
||||
*/
|
||||
public function getImageStringData($base64 = false)
|
||||
{
|
||||
$imageBinary = $this->getImageString();
|
||||
if ($imageBinary === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($base64) {
|
||||
return base64_encode($imageBinary);
|
||||
}
|
||||
|
||||
return bin2hex($imageBinary);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,31 +531,45 @@ class Image extends AbstractElement
|
||||
switch ($this->imageType) {
|
||||
case 'image/png':
|
||||
$this->imageCreateFunc = $this->sourceType == self::SOURCE_STRING ? 'imagecreatefromstring' : 'imagecreatefrompng';
|
||||
$this->imageFunc = 'imagepng';
|
||||
$this->imageFunc = function ($resource): void {
|
||||
imagepng($resource, null, $this->imageQuality);
|
||||
};
|
||||
$this->imageExtension = 'png';
|
||||
$this->imageQuality = -1;
|
||||
|
||||
break;
|
||||
case 'image/gif':
|
||||
$this->imageCreateFunc = $this->sourceType == self::SOURCE_STRING ? 'imagecreatefromstring' : 'imagecreatefromgif';
|
||||
$this->imageFunc = 'imagegif';
|
||||
$this->imageFunc = function ($resource): void {
|
||||
imagegif($resource);
|
||||
};
|
||||
$this->imageExtension = 'gif';
|
||||
$this->imageQuality = null;
|
||||
|
||||
break;
|
||||
case 'image/jpeg':
|
||||
case 'image/jpg':
|
||||
$this->imageCreateFunc = $this->sourceType == self::SOURCE_STRING ? 'imagecreatefromstring' : 'imagecreatefromjpeg';
|
||||
$this->imageFunc = 'imagejpeg';
|
||||
$this->imageFunc = function ($resource): void {
|
||||
imagejpeg($resource, null, $this->imageQuality);
|
||||
};
|
||||
$this->imageExtension = 'jpg';
|
||||
$this->imageQuality = 100;
|
||||
|
||||
break;
|
||||
case 'image/bmp':
|
||||
case 'image/x-ms-bmp':
|
||||
$this->imageType = 'image/bmp';
|
||||
$this->imageFunc = null;
|
||||
$this->imageExtension = 'bmp';
|
||||
$this->imageQuality = null;
|
||||
|
||||
break;
|
||||
case 'image/tiff':
|
||||
$this->imageType = 'image/tiff';
|
||||
$this->imageFunc = null;
|
||||
$this->imageExtension = 'tif';
|
||||
$this->imageQuality = null;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class Line extends AbstractElement
|
||||
/**
|
||||
* Line style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Line
|
||||
* @var ?\PhpOffice\PhpWord\Style\Line
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -44,7 +44,7 @@ class Line extends AbstractElement
|
||||
/**
|
||||
* Get line style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Line
|
||||
* @return ?\PhpOffice\PhpWord\Style\Line
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
|
||||
@@ -43,14 +43,14 @@ class Link extends AbstractElement
|
||||
/**
|
||||
* Font style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Font|string
|
||||
* @var null|\PhpOffice\PhpWord\Style\Font|string
|
||||
*/
|
||||
private $fontStyle;
|
||||
|
||||
/**
|
||||
* Paragraph style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Paragraph|string
|
||||
* @var null|\PhpOffice\PhpWord\Style\Paragraph|string
|
||||
*/
|
||||
private $paragraphStyle;
|
||||
|
||||
@@ -109,7 +109,7 @@ class Link extends AbstractElement
|
||||
/**
|
||||
* Get Text style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Font|string
|
||||
* @return null|\PhpOffice\PhpWord\Style\Font|string
|
||||
*/
|
||||
public function getFontStyle()
|
||||
{
|
||||
@@ -119,7 +119,7 @@ class Link extends AbstractElement
|
||||
/**
|
||||
* Get Paragraph style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Paragraph|string
|
||||
* @return null|\PhpOffice\PhpWord\Style\Paragraph|string
|
||||
*/
|
||||
public function getParagraphStyle()
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@ class ListItem extends AbstractElement
|
||||
/**
|
||||
* Element style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\ListItem
|
||||
* @var ?\PhpOffice\PhpWord\Style\ListItem
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -71,7 +71,7 @@ class ListItem extends AbstractElement
|
||||
/**
|
||||
* Get style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\ListItem
|
||||
* @return ?\PhpOffice\PhpWord\Style\ListItem
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ class ListItemRun extends TextRun
|
||||
/**
|
||||
* ListItem Style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\ListItem
|
||||
* @var ?\PhpOffice\PhpWord\Style\ListItem
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -66,7 +66,7 @@ class ListItemRun extends TextRun
|
||||
/**
|
||||
* Get ListItem style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\ListItem
|
||||
* @return ?\PhpOffice\PhpWord\Style\ListItem
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ class OLEObject extends AbstractElement
|
||||
/**
|
||||
* Image Style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Image
|
||||
* @var ?\PhpOffice\PhpWord\Style\Image
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -100,7 +100,7 @@ class OLEObject extends AbstractElement
|
||||
/**
|
||||
* Get object style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Image
|
||||
* @return ?\PhpOffice\PhpWord\Style\Image
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
|
||||
@@ -29,21 +29,21 @@ class PreserveText extends AbstractElement
|
||||
/**
|
||||
* Text content.
|
||||
*
|
||||
* @var array|string
|
||||
* @var null|array|string
|
||||
*/
|
||||
private $text;
|
||||
|
||||
/**
|
||||
* Text style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Font|string
|
||||
* @var null|\PhpOffice\PhpWord\Style\Font|string
|
||||
*/
|
||||
private $fontStyle;
|
||||
|
||||
/**
|
||||
* Paragraph style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Paragraph|string
|
||||
* @var null|\PhpOffice\PhpWord\Style\Paragraph|string
|
||||
*/
|
||||
private $paragraphStyle;
|
||||
|
||||
@@ -69,7 +69,7 @@ class PreserveText extends AbstractElement
|
||||
/**
|
||||
* Get Text style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Font|string
|
||||
* @return null|\PhpOffice\PhpWord\Style\Font|string
|
||||
*/
|
||||
public function getFontStyle()
|
||||
{
|
||||
@@ -79,7 +79,7 @@ class PreserveText extends AbstractElement
|
||||
/**
|
||||
* Get Paragraph style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Paragraph|string
|
||||
* @return null|\PhpOffice\PhpWord\Style\Paragraph|string
|
||||
*/
|
||||
public function getParagraphStyle()
|
||||
{
|
||||
@@ -89,7 +89,7 @@ class PreserveText extends AbstractElement
|
||||
/**
|
||||
* Get Text content.
|
||||
*
|
||||
* @return array|string
|
||||
* @return null|array|string
|
||||
*/
|
||||
public function getText()
|
||||
{
|
||||
|
||||
@@ -29,14 +29,14 @@ class Row extends AbstractElement
|
||||
/**
|
||||
* Row height.
|
||||
*
|
||||
* @var int
|
||||
* @var ?int
|
||||
*/
|
||||
private $height;
|
||||
|
||||
/**
|
||||
* Row style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Row
|
||||
* @var ?\PhpOffice\PhpWord\Style\Row
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -89,7 +89,7 @@ class Row extends AbstractElement
|
||||
/**
|
||||
* Get row style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Row
|
||||
* @return ?\PhpOffice\PhpWord\Style\Row
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
@@ -99,7 +99,7 @@ class Row extends AbstractElement
|
||||
/**
|
||||
* Get row height.
|
||||
*
|
||||
* @return int
|
||||
* @return ?int
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ class SDT extends Text
|
||||
/**
|
||||
* Value.
|
||||
*
|
||||
* @var bool|int|string
|
||||
* @var null|bool|int|string
|
||||
*/
|
||||
private $value;
|
||||
|
||||
@@ -100,7 +100,7 @@ class SDT extends Text
|
||||
/**
|
||||
* Get value.
|
||||
*
|
||||
* @return bool|int|string
|
||||
* @return null|bool|int|string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
@@ -110,7 +110,7 @@ class SDT extends Text
|
||||
/**
|
||||
* Set value.
|
||||
*
|
||||
* @param bool|int|string $value
|
||||
* @param null|bool|int|string $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@ class Section extends AbstractContainer
|
||||
/**
|
||||
* Section style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Section
|
||||
* @var ?\PhpOffice\PhpWord\Style\Section
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -60,7 +60,7 @@ class Section extends AbstractContainer
|
||||
* Create new instance.
|
||||
*
|
||||
* @param int $sectionCount
|
||||
* @param null|array|\PhpOffice\PhpWord\Style $style
|
||||
* @param null|array|\PhpOffice\PhpWord\Style|string $style
|
||||
*/
|
||||
public function __construct($sectionCount, $style = null)
|
||||
{
|
||||
@@ -87,7 +87,7 @@ class Section extends AbstractContainer
|
||||
/**
|
||||
* Get section style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Section
|
||||
* @return ?\PhpOffice\PhpWord\Style\Section
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
@@ -154,8 +154,6 @@ class Section extends AbstractContainer
|
||||
|
||||
/**
|
||||
* Set the footnote properties.
|
||||
*
|
||||
* @param FootnoteProperties $footnoteProperties
|
||||
*/
|
||||
public function setFootnoteProperties(?FootnoteProperties $footnoteProperties = null): void
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ class Shape extends AbstractElement
|
||||
/**
|
||||
* Shape style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Shape
|
||||
* @var ?\PhpOffice\PhpWord\Style\Shape
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -80,7 +80,7 @@ class Shape extends AbstractElement
|
||||
/**
|
||||
* Get shape style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Shape
|
||||
* @return ?\PhpOffice\PhpWord\Style\Shape
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@ class Table extends AbstractElement
|
||||
/**
|
||||
* Table style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Table
|
||||
* @var ?\PhpOffice\PhpWord\Style\Table
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -41,7 +41,7 @@ class Table extends AbstractElement
|
||||
/**
|
||||
* Table width.
|
||||
*
|
||||
* @var int
|
||||
* @var ?int
|
||||
*/
|
||||
private $width;
|
||||
|
||||
@@ -102,7 +102,7 @@ class Table extends AbstractElement
|
||||
/**
|
||||
* Get table style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Table
|
||||
* @return null|\PhpOffice\PhpWord\Style\Table|string
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
@@ -112,7 +112,7 @@ class Table extends AbstractElement
|
||||
/**
|
||||
* Get table width.
|
||||
*
|
||||
* @return int
|
||||
* @return ?int
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ class Text extends AbstractElement
|
||||
/**
|
||||
* Text content.
|
||||
*
|
||||
* @var string
|
||||
* @var ?string
|
||||
*/
|
||||
protected $text;
|
||||
|
||||
@@ -147,7 +147,7 @@ class Text extends AbstractElement
|
||||
/**
|
||||
* Get Text content.
|
||||
*
|
||||
* @return string
|
||||
* @return ?string
|
||||
*/
|
||||
public function getText()
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ class TextBox extends AbstractContainer
|
||||
/**
|
||||
* TextBox style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\TextBox
|
||||
* @var ?\PhpOffice\PhpWord\Style\TextBox
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -51,7 +51,7 @@ class TextBox extends AbstractContainer
|
||||
/**
|
||||
* Get textbox style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\TextBox
|
||||
* @return ?\PhpOffice\PhpWord\Style\TextBox
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
|
||||
@@ -28,14 +28,14 @@ class TextBreak extends AbstractElement
|
||||
/**
|
||||
* Paragraph style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Paragraph|string
|
||||
* @var null|\PhpOffice\PhpWord\Style\Paragraph|string
|
||||
*/
|
||||
private $paragraphStyle;
|
||||
|
||||
/**
|
||||
* Text style.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Font|string
|
||||
* @var null|\PhpOffice\PhpWord\Style\Font|string
|
||||
*/
|
||||
private $fontStyle;
|
||||
|
||||
@@ -82,7 +82,7 @@ class TextBreak extends AbstractElement
|
||||
/**
|
||||
* Get Text style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Font|string
|
||||
* @return null|\PhpOffice\PhpWord\Style\Font|string
|
||||
*/
|
||||
public function getFontStyle()
|
||||
{
|
||||
@@ -113,7 +113,7 @@ class TextBreak extends AbstractElement
|
||||
/**
|
||||
* Get Paragraph style.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Paragraph|string
|
||||
* @return null|\PhpOffice\PhpWord\Style\Paragraph|string
|
||||
*/
|
||||
public function getParagraphStyle()
|
||||
{
|
||||
|
||||
@@ -78,4 +78,16 @@ class TextRun extends AbstractContainer
|
||||
|
||||
return $this->paragraphStyle;
|
||||
}
|
||||
|
||||
public function getText(): string
|
||||
{
|
||||
$outstr = '';
|
||||
foreach ($this->getElements() as $element) {
|
||||
if ($element instanceof Text) {
|
||||
$outstr .= $element->getText();
|
||||
}
|
||||
}
|
||||
|
||||
return $outstr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class Title extends AbstractElement
|
||||
/**
|
||||
* Name of the heading style, e.g. 'Heading1'.
|
||||
*
|
||||
* @var string
|
||||
* @var ?string
|
||||
*/
|
||||
private $style;
|
||||
|
||||
@@ -54,13 +54,20 @@ class Title extends AbstractElement
|
||||
*/
|
||||
protected $collectionRelation = true;
|
||||
|
||||
/**
|
||||
* Page number.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $pageNumber;
|
||||
|
||||
/**
|
||||
* Create a new Title Element.
|
||||
*
|
||||
* @param string|TextRun $text
|
||||
* @param int $depth
|
||||
*/
|
||||
public function __construct($text, $depth = 1)
|
||||
public function __construct($text, $depth = 1, ?int $pageNumber = null)
|
||||
{
|
||||
if (is_string($text)) {
|
||||
$this->text = SharedText::toUTF8($text);
|
||||
@@ -75,12 +82,16 @@ class Title extends AbstractElement
|
||||
if (array_key_exists($styleName, Style::getStyles())) {
|
||||
$this->style = str_replace('_', '', $styleName);
|
||||
}
|
||||
|
||||
if ($pageNumber !== null) {
|
||||
$this->pageNumber = $pageNumber;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title Text content.
|
||||
*
|
||||
* @return string
|
||||
* @return string|TextRun
|
||||
*/
|
||||
public function getText()
|
||||
{
|
||||
@@ -100,10 +111,18 @@ class Title extends AbstractElement
|
||||
/**
|
||||
* Get Title style.
|
||||
*
|
||||
* @return string
|
||||
* @return ?string
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
return $this->style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page number.
|
||||
*/
|
||||
public function getPageNumber(): ?int
|
||||
{
|
||||
return $this->pageNumber;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace PhpOffice\PhpWord\Escaper;
|
||||
abstract class AbstractEscaper implements EscaperInterface
|
||||
{
|
||||
/**
|
||||
* @param string $input
|
||||
* @param ?string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@@ -47,7 +47,7 @@ class Rtf extends AbstractEscaper
|
||||
/**
|
||||
* @see http://www.randomchaos.com/documents/?source=php_and_unicode
|
||||
*
|
||||
* @param string $input
|
||||
* @param ?string $input
|
||||
*/
|
||||
protected function escapeSingleValue($input)
|
||||
{
|
||||
|
||||
@@ -41,7 +41,6 @@ class Media
|
||||
* @param string $container section|headerx|footerx|footnote|endnote
|
||||
* @param string $mediaType image|object|link
|
||||
* @param string $source
|
||||
* @param \PhpOffice\PhpWord\Element\Image $image
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -74,8 +73,7 @@ class Media
|
||||
$mediaData['imageType'] = $image->getImageType();
|
||||
if ($isMemImage) {
|
||||
$mediaData['isMemImage'] = true;
|
||||
$mediaData['createFunction'] = $image->getImageCreateFunction();
|
||||
$mediaData['imageFunction'] = $image->getImageFunction();
|
||||
$mediaData['imageString'] = $image->getImageString();
|
||||
}
|
||||
$target = "{$container}_image{$mediaTypeCount}.{$extension}";
|
||||
$image->setTarget($target);
|
||||
|
||||
@@ -441,7 +441,7 @@ class DocInfo
|
||||
*
|
||||
* @param string $propertyName
|
||||
*
|
||||
* @return string
|
||||
* @return ?string
|
||||
*/
|
||||
public function getCustomPropertyType($propertyName)
|
||||
{
|
||||
|
||||
@@ -114,7 +114,7 @@ class Settings
|
||||
/**
|
||||
* Theme Font Languages.
|
||||
*
|
||||
* @var Language
|
||||
* @var ?Language
|
||||
*/
|
||||
private $themeFontLang;
|
||||
|
||||
@@ -149,7 +149,7 @@ class Settings
|
||||
/**
|
||||
* The allowed amount of whitespace before hyphenation is applied.
|
||||
*
|
||||
* @var null|float
|
||||
* @var null|float|int
|
||||
*/
|
||||
private $hyphenationZone;
|
||||
|
||||
@@ -160,6 +160,13 @@ class Settings
|
||||
*/
|
||||
private $doNotHyphenateCaps;
|
||||
|
||||
/**
|
||||
* Enable or disable book-folded printing.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $bookFoldPrinting = false;
|
||||
|
||||
/**
|
||||
* @return Protection
|
||||
*/
|
||||
@@ -213,7 +220,7 @@ class Settings
|
||||
/**
|
||||
* Hide spelling errors.
|
||||
*
|
||||
* @param bool $hideSpellingErrors
|
||||
* @param ?bool $hideSpellingErrors
|
||||
*/
|
||||
public function setHideSpellingErrors($hideSpellingErrors): void
|
||||
{
|
||||
@@ -233,7 +240,7 @@ class Settings
|
||||
/**
|
||||
* Hide grammatical errors.
|
||||
*
|
||||
* @param bool $hideGrammaticalErrors
|
||||
* @param ?bool $hideGrammaticalErrors
|
||||
*/
|
||||
public function setHideGrammaticalErrors($hideGrammaticalErrors): void
|
||||
{
|
||||
@@ -249,7 +256,7 @@ class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $evenAndOddHeaders
|
||||
* @param ?bool $evenAndOddHeaders
|
||||
*/
|
||||
public function setEvenAndOddHeaders($evenAndOddHeaders): void
|
||||
{
|
||||
@@ -268,8 +275,6 @@ class Settings
|
||||
|
||||
/**
|
||||
* Set the Visibility of Annotation Types.
|
||||
*
|
||||
* @param TrackChangesView $trackChangesView
|
||||
*/
|
||||
public function setRevisionView(?TrackChangesView $trackChangesView = null): void
|
||||
{
|
||||
@@ -285,7 +290,7 @@ class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $trackRevisions
|
||||
* @param ?bool $trackRevisions
|
||||
*/
|
||||
public function setTrackRevisions($trackRevisions): void
|
||||
{
|
||||
@@ -301,7 +306,7 @@ class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $doNotTrackMoves
|
||||
* @param ?bool $doNotTrackMoves
|
||||
*/
|
||||
public function setDoNotTrackMoves($doNotTrackMoves): void
|
||||
{
|
||||
@@ -317,7 +322,7 @@ class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $doNotTrackFormatting
|
||||
* @param ?bool $doNotTrackFormatting
|
||||
*/
|
||||
public function setDoNotTrackFormatting($doNotTrackFormatting): void
|
||||
{
|
||||
@@ -364,22 +369,20 @@ class Settings
|
||||
|
||||
/**
|
||||
* Returns the Language.
|
||||
*
|
||||
* @return Language
|
||||
*/
|
||||
public function getThemeFontLang()
|
||||
public function getThemeFontLang(): ?Language
|
||||
{
|
||||
return $this->themeFontLang;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the Language for this document.
|
||||
*
|
||||
* @param Language $themeFontLang
|
||||
* Sets the Language for this document.
|
||||
*/
|
||||
public function setThemeFontLang($themeFontLang): void
|
||||
public function setThemeFontLang(Language $themeFontLang): self
|
||||
{
|
||||
$this->themeFontLang = $themeFontLang;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -391,7 +394,7 @@ class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $updateFields
|
||||
* @param ?bool $updateFields
|
||||
*/
|
||||
public function setUpdateFields($updateFields): void
|
||||
{
|
||||
@@ -451,7 +454,7 @@ class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|float
|
||||
* @return null|float|int
|
||||
*/
|
||||
public function getHyphenationZone()
|
||||
{
|
||||
@@ -459,7 +462,7 @@ class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $hyphenationZone Measurement unit is twip
|
||||
* @param null|float|int $hyphenationZone Measurement unit is twip
|
||||
*/
|
||||
public function setHyphenationZone($hyphenationZone): void
|
||||
{
|
||||
@@ -481,4 +484,16 @@ class Settings
|
||||
{
|
||||
$this->doNotHyphenateCaps = (bool) $doNotHyphenateCaps;
|
||||
}
|
||||
|
||||
public function hasBookFoldPrinting(): bool
|
||||
{
|
||||
return $this->bookFoldPrinting;
|
||||
}
|
||||
|
||||
public function setBookFoldPrinting(bool $bookFoldPrinting): self
|
||||
{
|
||||
$this->bookFoldPrinting = $bookFoldPrinting;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
51
vendor/phpoffice/phpword/src/PhpWord/PhpWord.php
vendored
51
vendor/phpoffice/phpword/src/PhpWord/PhpWord.php
vendored
@@ -77,6 +77,7 @@ class PhpWord
|
||||
// Reset Media and styles
|
||||
Media::resetElements();
|
||||
Style::resetStyles();
|
||||
Settings::setDefaultRtl(null);
|
||||
|
||||
// Collection
|
||||
$collections = ['Bookmarks', 'Titles', 'Footnotes', 'Endnotes', 'Charts', 'Comments'];
|
||||
@@ -211,7 +212,7 @@ class PhpWord
|
||||
/**
|
||||
* Create new section.
|
||||
*
|
||||
* @param array $style
|
||||
* @param null|array|string $style
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Element\Section
|
||||
*/
|
||||
@@ -325,4 +326,52 @@ class PhpWord
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new section.
|
||||
*
|
||||
* @deprecated 0.10.0
|
||||
*
|
||||
* @param array $settings
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Element\Section
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function createSection($settings = null)
|
||||
{
|
||||
return $this->addSection($settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document properties object.
|
||||
*
|
||||
* @deprecated 0.12.0
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Metadata\DocInfo
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getDocumentProperties()
|
||||
{
|
||||
return $this->getDocInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document properties object.
|
||||
*
|
||||
* @deprecated 0.12.0
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Metadata\DocInfo $documentProperties
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function setDocumentProperties($documentProperties)
|
||||
{
|
||||
$this->metadata['Document'] = $documentProperties;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,13 @@ abstract class AbstractReader implements ReaderInterface
|
||||
*/
|
||||
protected $fileHandle;
|
||||
|
||||
/**
|
||||
* Load images.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $imageLoading = true;
|
||||
|
||||
/**
|
||||
* Read data only?
|
||||
*
|
||||
@@ -67,6 +74,18 @@ abstract class AbstractReader implements ReaderInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasImageLoading(): bool
|
||||
{
|
||||
return $this->imageLoading;
|
||||
}
|
||||
|
||||
public function setImageLoading(bool $value): self
|
||||
{
|
||||
$this->imageLoading = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open file for reading.
|
||||
*
|
||||
|
||||
@@ -82,6 +82,12 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
*/
|
||||
private $arraySections = [];
|
||||
|
||||
/** @var string */
|
||||
private $summaryInformation;
|
||||
|
||||
/** @var string */
|
||||
private $documentSummaryInformation;
|
||||
|
||||
const VERSION_97 = '97';
|
||||
const VERSION_2000 = '2000';
|
||||
const VERSION_2002 = '2002';
|
||||
@@ -150,9 +156,9 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
// Get Data stream
|
||||
$this->dataObjectPool = $ole->getStream($ole->wrkObjectPool);
|
||||
// Get Summary Information data
|
||||
$this->_SummaryInformation = $ole->getStream($ole->summaryInformation);
|
||||
$this->summaryInformation = $ole->getStream($ole->summaryInformation);
|
||||
// Get Document Summary Information data
|
||||
$this->_DocumentSummaryInformation = $ole->getStream($ole->docSummaryInfos);
|
||||
$this->documentSummaryInformation = $ole->getStream($ole->docSummaryInfos);
|
||||
}
|
||||
|
||||
private function getNumInLcb($lcb, $iSize)
|
||||
@@ -1131,7 +1137,7 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
/**
|
||||
* Section and information about them.
|
||||
*
|
||||
* @see : http://msdn.microsoft.com/en-us/library/dd924458%28v=office.12%29.aspx
|
||||
* @see http://msdn.microsoft.com/en-us/library/dd924458%28v=office.12%29.aspx
|
||||
*/
|
||||
private function readRecordPlcfSed(): void
|
||||
{
|
||||
@@ -1145,7 +1151,7 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
$posMem += 4;
|
||||
|
||||
// PlcfSed : aSed
|
||||
//@see : http://msdn.microsoft.com/en-us/library/dd950194%28v=office.12%29.aspx
|
||||
//@see http://msdn.microsoft.com/en-us/library/dd950194%28v=office.12%29.aspx
|
||||
$numSed = $this->getNumInLcb($this->arrayFib['lcbPlcfSed'], 12);
|
||||
|
||||
$aSed = [];
|
||||
@@ -1177,7 +1183,7 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
/**
|
||||
* Specifies the fonts that are used in the document.
|
||||
*
|
||||
* @see : http://msdn.microsoft.com/en-us/library/dd943880%28v=office.12%29.aspx
|
||||
* @see http://msdn.microsoft.com/en-us/library/dd943880%28v=office.12%29.aspx
|
||||
*/
|
||||
private function readRecordSttbfFfn(): void
|
||||
{
|
||||
@@ -1468,7 +1474,7 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
$offset = $offsetBase;
|
||||
|
||||
// ChpxFkp
|
||||
// @see : http://msdn.microsoft.com/en-us/library/dd910989%28v=office.12%29.aspx
|
||||
// @see http://msdn.microsoft.com/en-us/library/dd910989%28v=office.12%29.aspx
|
||||
$numRGFC = self::getInt1d($this->dataWorkDocument, $offset + 511);
|
||||
$arrayRGFC = [];
|
||||
for ($inc = 0; $inc <= $numRGFC; ++$inc) {
|
||||
@@ -1491,7 +1497,7 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
|
||||
if ($rgb > 0) {
|
||||
// Chp Structure
|
||||
// @see : http://msdn.microsoft.com/en-us/library/dd772849%28v=office.12%29.aspx
|
||||
// @see http://msdn.microsoft.com/en-us/library/dd772849%28v=office.12%29.aspx
|
||||
$posRGB = $offsetBase + $rgb * 2;
|
||||
|
||||
$cb = self::getInt1d($this->dataWorkDocument, $posRGB);
|
||||
@@ -1926,12 +1932,13 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
// $operand = self::getInt2d($data, $pos);
|
||||
$pos += 2;
|
||||
$cbNum -= 2;
|
||||
|
||||
// $ipat = ($operand >> 0) && bindec('111111');
|
||||
// $icoBack = ($operand >> 6) && bindec('11111');
|
||||
// $icoFore = ($operand >> 11) && bindec('11111');
|
||||
break;
|
||||
// sprmCCv
|
||||
//@see : http://msdn.microsoft.com/en-us/library/dd952824%28v=office.12%29.aspx
|
||||
//@see http://msdn.microsoft.com/en-us/library/dd952824%28v=office.12%29.aspx
|
||||
case 0x70:
|
||||
$red = str_pad(dechex(self::getInt1d($this->dataWorkDocument, $pos)), 2, '0', STR_PAD_LEFT);
|
||||
++$pos;
|
||||
@@ -2042,7 +2049,7 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
// HFD > clsid
|
||||
$sprmCPicLocation += 16;
|
||||
// HFD > hyperlink
|
||||
//@see : http://msdn.microsoft.com/en-us/library/dd909835%28v=office.12%29.aspx
|
||||
//@see http://msdn.microsoft.com/en-us/library/dd909835%28v=office.12%29.aspx
|
||||
$streamVersion = self::getInt4d($this->dataData, $sprmCPicLocation);
|
||||
$sprmCPicLocation += 4;
|
||||
$data = self::getInt4d($this->dataData, $sprmCPicLocation);
|
||||
@@ -2110,8 +2117,8 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
}*/
|
||||
} else {
|
||||
// Pictures
|
||||
//@see : http://msdn.microsoft.com/en-us/library/dd925458%28v=office.12%29.aspx
|
||||
//@see : http://msdn.microsoft.com/en-us/library/dd926136%28v=office.12%29.aspx
|
||||
//@see http://msdn.microsoft.com/en-us/library/dd925458%28v=office.12%29.aspx
|
||||
//@see http://msdn.microsoft.com/en-us/library/dd926136%28v=office.12%29.aspx
|
||||
// PICF : lcb
|
||||
$sprmCPicLocation += 4;
|
||||
// PICF : cbHeader
|
||||
@@ -2198,13 +2205,13 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
$sprmCPicLocation += $shapeRH['recLen'];
|
||||
}
|
||||
// picture : rgfb
|
||||
//@see : http://msdn.microsoft.com/en-us/library/dd950560%28v=office.12%29.aspx
|
||||
//@see http://msdn.microsoft.com/en-us/library/dd950560%28v=office.12%29.aspx
|
||||
$fileBlockRH = $this->loadRecordHeader($this->dataData, $sprmCPicLocation);
|
||||
while ($fileBlockRH['recType'] == 0xF007 || ($fileBlockRH['recType'] >= 0xF018 && $fileBlockRH['recType'] <= 0xF117)) {
|
||||
$sprmCPicLocation += 8;
|
||||
switch ($fileBlockRH['recType']) {
|
||||
// OfficeArtFBSE
|
||||
//@see : http://msdn.microsoft.com/en-us/library/dd944923%28v=office.12%29.aspx
|
||||
//@see http://msdn.microsoft.com/en-us/library/dd944923%28v=office.12%29.aspx
|
||||
case 0xF007:
|
||||
// btWin32
|
||||
++$sprmCPicLocation;
|
||||
@@ -2239,7 +2246,7 @@ class MsDoc extends AbstractReader implements ReaderInterface
|
||||
}
|
||||
}
|
||||
// embeddedBlip
|
||||
//@see : http://msdn.microsoft.com/en-us/library/dd910081%28v=office.12%29.aspx
|
||||
//@see http://msdn.microsoft.com/en-us/library/dd910081%28v=office.12%29.aspx
|
||||
$embeddedBlipRH = $this->loadRecordHeader($this->dataData, $sprmCPicLocation);
|
||||
switch ($embeddedBlipRH['recType']) {
|
||||
case self::OFFICEARTBLIPJPG:
|
||||
|
||||
@@ -53,13 +53,8 @@ class ODText extends AbstractReader implements ReaderInterface
|
||||
|
||||
/**
|
||||
* Read document part.
|
||||
*
|
||||
* @param array $relationships
|
||||
* @param string $partName
|
||||
* @param string $docFile
|
||||
* @param string $xmlFile
|
||||
*/
|
||||
private function readPart(PhpWord $phpWord, $relationships, $partName, $docFile, $xmlFile): void
|
||||
private function readPart(PhpWord $phpWord, array $relationships, string $partName, string $docFile, string $xmlFile): void
|
||||
{
|
||||
$partClass = "PhpOffice\\PhpWord\\Reader\\ODText\\{$partName}";
|
||||
if (class_exists($partClass)) {
|
||||
@@ -72,12 +67,8 @@ class ODText extends AbstractReader implements ReaderInterface
|
||||
|
||||
/**
|
||||
* Read all relationship files.
|
||||
*
|
||||
* @param string $docFile
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function readRelationships($docFile)
|
||||
private function readRelationships(string $docFile): array
|
||||
{
|
||||
$rels = [];
|
||||
$xmlFile = 'META-INF/manifest.xml';
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
namespace PhpOffice\PhpWord\Reader\ODText;
|
||||
|
||||
use DateTime;
|
||||
use DOMElement;
|
||||
use DOMNodeList;
|
||||
use PhpOffice\Math\Reader\MathML;
|
||||
use PhpOffice\PhpWord\Element\Section;
|
||||
use PhpOffice\PhpWord\Element\TrackChange;
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\Shared\XMLReader;
|
||||
@@ -29,6 +33,9 @@ use PhpOffice\PhpWord\Shared\XMLReader;
|
||||
*/
|
||||
class Content extends AbstractPart
|
||||
{
|
||||
/** @var ?Section */
|
||||
private $section;
|
||||
|
||||
/**
|
||||
* Read content.xml.
|
||||
*/
|
||||
@@ -40,48 +47,112 @@ class Content extends AbstractPart
|
||||
$trackedChanges = [];
|
||||
|
||||
$nodes = $xmlReader->getElements('office:body/office:text/*');
|
||||
$this->section = null;
|
||||
$this->processNodes($nodes, $xmlReader, $phpWord);
|
||||
$this->section = null;
|
||||
}
|
||||
|
||||
/** @param DOMNodeList<DOMElement> $nodes */
|
||||
public function processNodes(DOMNodeList $nodes, XMLReader $xmlReader, PhpWord $phpWord): void
|
||||
{
|
||||
if ($nodes->length > 0) {
|
||||
$section = $phpWord->addSection();
|
||||
foreach ($nodes as $node) {
|
||||
// $styleName = $xmlReader->getAttribute('text:style-name', $node);
|
||||
switch ($node->nodeName) {
|
||||
case 'text:h': // Heading
|
||||
$depth = $xmlReader->getAttribute('text:outline-level', $node);
|
||||
$section->addTitle($node->nodeValue, $depth);
|
||||
$this->getSection($phpWord)->addTitle($node->nodeValue, $depth);
|
||||
|
||||
break;
|
||||
case 'text:p': // Paragraph
|
||||
$children = $node->childNodes;
|
||||
foreach ($children as $child) {
|
||||
switch ($child->nodeName) {
|
||||
case 'text:change-start':
|
||||
$changeId = $child->getAttribute('text:change-id');
|
||||
if (isset($trackedChanges[$changeId])) {
|
||||
$changed = $trackedChanges[$changeId];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'text:change-end':
|
||||
unset($changed);
|
||||
|
||||
break;
|
||||
case 'text:change':
|
||||
$changeId = $child->getAttribute('text:change-id');
|
||||
if (isset($trackedChanges[$changeId])) {
|
||||
$changed = $trackedChanges[$changeId];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
$styleName = $xmlReader->getAttribute('text:style-name', $node);
|
||||
if (substr($styleName, 0, 2) === 'SB') {
|
||||
break;
|
||||
}
|
||||
$element = $xmlReader->getElement('draw:frame/draw:object', $node);
|
||||
if ($element) {
|
||||
$mathFile = str_replace('./', '', $element->getAttribute('xlink:href')) . '/content.xml';
|
||||
|
||||
$element = $section->addText($node->nodeValue);
|
||||
if (isset($changed) && is_array($changed)) {
|
||||
$element->setTrackChange($changed['changed']);
|
||||
if (isset($changed['textNodes'])) {
|
||||
foreach ($changed['textNodes'] as $changedNode) {
|
||||
$element = $section->addText($changedNode->nodeValue);
|
||||
$element->setTrackChange($changed['changed']);
|
||||
$xmlReaderObject = new XMLReader();
|
||||
$mathElement = $xmlReaderObject->getDomFromZip($this->docFile, $mathFile);
|
||||
if ($mathElement) {
|
||||
$mathXML = $mathElement->saveXML($mathElement);
|
||||
|
||||
if (is_string($mathXML)) {
|
||||
$reader = new MathML();
|
||||
$math = $reader->read($mathXML);
|
||||
|
||||
$this->getSection($phpWord)->addFormula($math);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$children = $node->childNodes;
|
||||
$spans = false;
|
||||
/** @var DOMElement $child */
|
||||
foreach ($children as $child) {
|
||||
switch ($child->nodeName) {
|
||||
case 'text:change-start':
|
||||
$changeId = $child->getAttribute('text:change-id');
|
||||
if (isset($trackedChanges[$changeId])) {
|
||||
$changed = $trackedChanges[$changeId];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'text:change-end':
|
||||
unset($changed);
|
||||
|
||||
break;
|
||||
case 'text:change':
|
||||
$changeId = $child->getAttribute('text:change-id');
|
||||
if (isset($trackedChanges[$changeId])) {
|
||||
$changed = $trackedChanges[$changeId];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'text:span':
|
||||
$spans = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($spans) {
|
||||
$element = $this->getSection($phpWord)->addTextRun();
|
||||
foreach ($children as $child) {
|
||||
switch ($child->nodeName) {
|
||||
case 'text:span':
|
||||
/** @var DOMElement $child2 */
|
||||
foreach ($child->childNodes as $child2) {
|
||||
switch ($child2->nodeName) {
|
||||
case '#text':
|
||||
$element->addText($child2->nodeValue);
|
||||
|
||||
break;
|
||||
case 'text:tab':
|
||||
$element->addText("\t");
|
||||
|
||||
break;
|
||||
case 'text:s':
|
||||
$spaces = (int) $child2->getAttribute('text:c') ?: 1;
|
||||
$element->addText(str_repeat(' ', $spaces));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$element = $this->getSection($phpWord)->addText($node->nodeValue);
|
||||
}
|
||||
if (isset($changed) && is_array($changed)) {
|
||||
$element->setTrackChange($changed['changed']);
|
||||
if (isset($changed['textNodes'])) {
|
||||
foreach ($changed['textNodes'] as $changedNode) {
|
||||
$element = $this->getSection($phpWord)->addText($changedNode->nodeValue);
|
||||
$element->setTrackChange($changed['changed']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,7 +162,7 @@ class Content extends AbstractPart
|
||||
$listItems = $xmlReader->getElements('text:list-item/text:p', $node);
|
||||
foreach ($listItems as $listItem) {
|
||||
// $listStyleName = $xmlReader->getAttribute('text:style-name', $listItem);
|
||||
$section->addListItem($listItem->nodeValue, 0);
|
||||
$this->getSection($phpWord)->addListItem($listItem->nodeValue, 0);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -110,9 +181,26 @@ class Content extends AbstractPart
|
||||
$trackedChanges[$changedRegion->getAttribute('text:id')] = ['changed' => $changed, 'textNodes' => $textNodes];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'text:section': // Section
|
||||
// $sectionStyleName = $xmlReader->getAttribute('text:style-name', $listItem);
|
||||
$this->section = $phpWord->addSection();
|
||||
$children = $node->childNodes;
|
||||
$this->processNodes($children, $xmlReader, $phpWord);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getSection(PhpWord $phpWord): Section
|
||||
{
|
||||
$section = $this->section;
|
||||
if ($section === null) {
|
||||
$section = $this->section = $phpWord->addSection();
|
||||
}
|
||||
|
||||
return $section;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Reader;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpWord\Element\AbstractElement;
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\Reader\Word2007\AbstractPart;
|
||||
use PhpOffice\PhpWord\Shared\XMLReader;
|
||||
use PhpOffice\PhpWord\Shared\ZipArchive;
|
||||
|
||||
@@ -42,23 +45,34 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||
{
|
||||
$phpWord = new PhpWord();
|
||||
$relationships = $this->readRelationships($docFile);
|
||||
$commentRefs = [];
|
||||
|
||||
$steps = [
|
||||
['stepPart' => 'document', 'stepItems' => [
|
||||
'styles' => 'Styles',
|
||||
'numbering' => 'Numbering',
|
||||
]],
|
||||
['stepPart' => 'main', 'stepItems' => [
|
||||
'officeDocument' => 'Document',
|
||||
'core-properties' => 'DocPropsCore',
|
||||
'extended-properties' => 'DocPropsApp',
|
||||
'custom-properties' => 'DocPropsCustom',
|
||||
]],
|
||||
['stepPart' => 'document', 'stepItems' => [
|
||||
'endnotes' => 'Endnotes',
|
||||
'footnotes' => 'Footnotes',
|
||||
'settings' => 'Settings',
|
||||
]],
|
||||
[
|
||||
'stepPart' => 'document',
|
||||
'stepItems' => [
|
||||
'styles' => 'Styles',
|
||||
'numbering' => 'Numbering',
|
||||
],
|
||||
],
|
||||
[
|
||||
'stepPart' => 'main',
|
||||
'stepItems' => [
|
||||
'officeDocument' => 'Document',
|
||||
'core-properties' => 'DocPropsCore',
|
||||
'extended-properties' => 'DocPropsApp',
|
||||
'custom-properties' => 'DocPropsCustom',
|
||||
],
|
||||
],
|
||||
[
|
||||
'stepPart' => 'document',
|
||||
'stepItems' => [
|
||||
'endnotes' => 'Endnotes',
|
||||
'footnotes' => 'Footnotes',
|
||||
'settings' => 'Settings',
|
||||
'comments' => 'Comments',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($steps as $step) {
|
||||
@@ -72,7 +86,8 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||
if (isset($stepItems[$relType])) {
|
||||
$partName = $stepItems[$relType];
|
||||
$xmlFile = $relItem['target'];
|
||||
$this->readPart($phpWord, $relationships, $partName, $docFile, $xmlFile);
|
||||
$part = $this->readPart($phpWord, $relationships, $commentRefs, $partName, $docFile, $xmlFile);
|
||||
$commentRefs = $part->getCommentReferences();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,20 +98,23 @@ class Word2007 extends AbstractReader implements ReaderInterface
|
||||
/**
|
||||
* Read document part.
|
||||
*
|
||||
* @param array $relationships
|
||||
* @param string $partName
|
||||
* @param string $docFile
|
||||
* @param string $xmlFile
|
||||
* @param array<string, array<string, null|AbstractElement>> $commentRefs
|
||||
*/
|
||||
private function readPart(PhpWord $phpWord, $relationships, $partName, $docFile, $xmlFile): void
|
||||
private function readPart(PhpWord $phpWord, array $relationships, array $commentRefs, string $partName, string $docFile, string $xmlFile): AbstractPart
|
||||
{
|
||||
$partClass = "PhpOffice\\PhpWord\\Reader\\Word2007\\{$partName}";
|
||||
if (class_exists($partClass)) {
|
||||
/** @var \PhpOffice\PhpWord\Reader\Word2007\AbstractPart $part Type hint */
|
||||
$part = new $partClass($docFile, $xmlFile);
|
||||
$part->setRels($relationships);
|
||||
$part->read($phpWord);
|
||||
if (!class_exists($partClass)) {
|
||||
throw new Exception(sprintf('The part "%s" doesn\'t exist', $partClass));
|
||||
}
|
||||
|
||||
/** @var AbstractPart $part Type hint */
|
||||
$part = new $partClass($docFile, $xmlFile);
|
||||
$part->setImageLoading($this->hasImageLoading());
|
||||
$part->setRels($relationships);
|
||||
$part->setCommentReferences($commentRefs);
|
||||
$part->read($phpWord);
|
||||
|
||||
return $part;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,8 +19,11 @@ namespace PhpOffice\PhpWord\Reader\Word2007;
|
||||
|
||||
use DateTime;
|
||||
use DOMElement;
|
||||
use InvalidArgumentException;
|
||||
use PhpOffice\Math\Reader\OfficeMathML;
|
||||
use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType;
|
||||
use PhpOffice\PhpWord\Element\AbstractContainer;
|
||||
use PhpOffice\PhpWord\Element\AbstractElement;
|
||||
use PhpOffice\PhpWord\Element\TextRun;
|
||||
use PhpOffice\PhpWord\Element\TrackChange;
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
@@ -67,6 +70,20 @@ abstract class AbstractPart
|
||||
*/
|
||||
protected $rels = [];
|
||||
|
||||
/**
|
||||
* Comment references.
|
||||
*
|
||||
* @var array<string, array<string, AbstractElement>>
|
||||
*/
|
||||
protected $commentRefs = [];
|
||||
|
||||
/**
|
||||
* Image Loading.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $imageLoading = true;
|
||||
|
||||
/**
|
||||
* Read part.
|
||||
*/
|
||||
@@ -94,6 +111,74 @@ abstract class AbstractPart
|
||||
$this->rels = $value;
|
||||
}
|
||||
|
||||
public function setImageLoading(bool $value): self
|
||||
{
|
||||
$this->imageLoading = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasImageLoading(): bool
|
||||
{
|
||||
return $this->imageLoading;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get comment references.
|
||||
*
|
||||
* @return array<string, array<string, null|AbstractElement>>
|
||||
*/
|
||||
public function getCommentReferences(): array
|
||||
{
|
||||
return $this->commentRefs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set comment references.
|
||||
*
|
||||
* @param array<string, array<string, null|AbstractElement>> $commentRefs
|
||||
*/
|
||||
public function setCommentReferences(array $commentRefs): self
|
||||
{
|
||||
$this->commentRefs = $commentRefs;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set comment reference.
|
||||
*/
|
||||
private function setCommentReference(string $type, string $id, AbstractElement $element): self
|
||||
{
|
||||
if (!in_array($type, ['start', 'end'])) {
|
||||
throw new InvalidArgumentException('Type must be "start" or "end"');
|
||||
}
|
||||
|
||||
if (!array_key_exists($id, $this->commentRefs)) {
|
||||
$this->commentRefs[$id] = [
|
||||
'start' => null,
|
||||
'end' => null,
|
||||
];
|
||||
}
|
||||
$this->commentRefs[$id][$type] = $element;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get comment reference.
|
||||
*
|
||||
* @return array<string, null|AbstractElement>
|
||||
*/
|
||||
protected function getCommentReference(string $id): array
|
||||
{
|
||||
if (!array_key_exists($id, $this->commentRefs)) {
|
||||
throw new InvalidArgumentException(sprintf('Comment with id %s isn\'t referenced in document', $id));
|
||||
}
|
||||
|
||||
return $this->commentRefs[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read w:p.
|
||||
*
|
||||
@@ -105,12 +190,7 @@ abstract class AbstractPart
|
||||
protected function readParagraph(XMLReader $xmlReader, DOMElement $domNode, $parent, $docPart = 'document'): void
|
||||
{
|
||||
// Paragraph style
|
||||
$paragraphStyle = null;
|
||||
$headingDepth = null;
|
||||
if ($xmlReader->elementExists('w:pPr', $domNode)) {
|
||||
$paragraphStyle = $this->readParagraphStyle($xmlReader, $domNode);
|
||||
$headingDepth = $this->getHeadingDepth($paragraphStyle);
|
||||
}
|
||||
$paragraphStyle = $xmlReader->elementExists('w:pPr', $domNode) ? $this->readParagraphStyle($xmlReader, $domNode) : null;
|
||||
|
||||
// PreserveText
|
||||
if ($xmlReader->elementExists('w:r/w:instrText', $domNode)) {
|
||||
@@ -137,8 +217,27 @@ abstract class AbstractPart
|
||||
}
|
||||
}
|
||||
$parent->addPreserveText(htmlspecialchars($textContent, ENT_QUOTES, 'UTF-8'), $fontStyle, $paragraphStyle);
|
||||
} elseif ($xmlReader->elementExists('w:pPr/w:numPr', $domNode)) {
|
||||
// List item
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Formula
|
||||
$xmlReader->registerNamespace('m', 'http://schemas.openxmlformats.org/officeDocument/2006/math');
|
||||
if ($xmlReader->elementExists('m:oMath', $domNode)) {
|
||||
$mathElement = $xmlReader->getElement('m:oMath', $domNode);
|
||||
$mathXML = $mathElement->ownerDocument->saveXML($mathElement);
|
||||
if (is_string($mathXML)) {
|
||||
$reader = new OfficeMathML();
|
||||
$math = $reader->read($mathXML);
|
||||
|
||||
$parent->addFormula($math);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// List item
|
||||
if ($xmlReader->elementExists('w:pPr/w:numPr', $domNode)) {
|
||||
$numId = $xmlReader->getAttribute('w:val', $domNode, 'w:pPr/w:numPr/w:numId');
|
||||
$levelId = $xmlReader->getAttribute('w:val', $domNode, 'w:pPr/w:numPr/w:ilvl');
|
||||
$nodes = $xmlReader->getElements('*', $domNode);
|
||||
@@ -148,10 +247,15 @@ abstract class AbstractPart
|
||||
foreach ($nodes as $node) {
|
||||
$this->readRun($xmlReader, $node, $listItemRun, $docPart, $paragraphStyle);
|
||||
}
|
||||
} elseif ($headingDepth !== null) {
|
||||
// Heading or Title
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Heading or Title
|
||||
$headingDepth = $xmlReader->elementExists('w:pPr', $domNode) ? $this->getHeadingDepth($paragraphStyle) : null;
|
||||
if ($headingDepth !== null) {
|
||||
$textContent = null;
|
||||
$nodes = $xmlReader->getElements('w:r', $domNode);
|
||||
$nodes = $xmlReader->getElements('w:r|w:hyperlink', $domNode);
|
||||
if ($nodes->length === 1) {
|
||||
$textContent = htmlspecialchars($xmlReader->getValue('w:t', $nodes->item(0)), ENT_QUOTES, 'UTF-8');
|
||||
} else {
|
||||
@@ -161,17 +265,19 @@ abstract class AbstractPart
|
||||
}
|
||||
}
|
||||
$parent->addTitle($textContent, $headingDepth);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Text and TextRun
|
||||
$textRunContainers = $xmlReader->countElements('w:r|w:ins|w:del|w:hyperlink|w:smartTag|w:commentReference|w:commentRangeStart|w:commentRangeEnd', $domNode);
|
||||
if (0 === $textRunContainers) {
|
||||
$parent->addTextBreak(null, $paragraphStyle);
|
||||
} else {
|
||||
// Text and TextRun
|
||||
$textRunContainers = $xmlReader->countElements('w:r|w:ins|w:del|w:hyperlink|w:smartTag', $domNode);
|
||||
if (0 === $textRunContainers) {
|
||||
$parent->addTextBreak(null, $paragraphStyle);
|
||||
} else {
|
||||
$nodes = $xmlReader->getElements('*', $domNode);
|
||||
$paragraph = $parent->addTextRun($paragraphStyle);
|
||||
foreach ($nodes as $node) {
|
||||
$this->readRun($xmlReader, $node, $paragraph, $docPart, $paragraphStyle);
|
||||
}
|
||||
$nodes = $xmlReader->getElements('*', $domNode);
|
||||
$paragraph = $parent->addTextRun($paragraphStyle);
|
||||
foreach ($nodes as $node) {
|
||||
$this->readRun($xmlReader, $node, $paragraph, $docPart, $paragraphStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,8 +285,6 @@ abstract class AbstractPart
|
||||
/**
|
||||
* Returns the depth of the Heading, returns 0 for a Title.
|
||||
*
|
||||
* @param array $paragraphStyle
|
||||
*
|
||||
* @return null|number
|
||||
*/
|
||||
private function getHeadingDepth(?array $paragraphStyle = null)
|
||||
@@ -211,7 +315,7 @@ abstract class AbstractPart
|
||||
*/
|
||||
protected function readRun(XMLReader $xmlReader, DOMElement $domNode, $parent, $docPart, $paragraphStyle = null): void
|
||||
{
|
||||
if (in_array($domNode->nodeName, ['w:ins', 'w:del', 'w:smartTag', 'w:hyperlink'])) {
|
||||
if (in_array($domNode->nodeName, ['w:ins', 'w:del', 'w:smartTag', 'w:hyperlink', 'w:commentReference'])) {
|
||||
$nodes = $xmlReader->getElements('*', $domNode);
|
||||
foreach ($nodes as $node) {
|
||||
$this->readRun($xmlReader, $node, $parent, $docPart, $paragraphStyle);
|
||||
@@ -223,6 +327,17 @@ abstract class AbstractPart
|
||||
$this->readRunChild($xmlReader, $node, $parent, $docPart, $paragraphStyle, $fontStyle);
|
||||
}
|
||||
}
|
||||
|
||||
if ($xmlReader->elementExists('.//*["commentReference"=local-name()]', $domNode)) {
|
||||
$node = iterator_to_array($xmlReader->getElements('.//*["commentReference"=local-name()]', $domNode))[0];
|
||||
$attributeIdentifier = $node->attributes->getNamedItem('id');
|
||||
if ($attributeIdentifier) {
|
||||
$id = $attributeIdentifier->nodeValue;
|
||||
|
||||
$this->setCommentReference('start', $id, $parent->getElement($parent->countElements() - 1));
|
||||
$this->setCommentReference('end', $id, $parent->getElement($parent->countElements() - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,7 +364,7 @@ abstract class AbstractPart
|
||||
// Image
|
||||
$rId = $xmlReader->getAttribute('r:id', $node, 'v:shape/v:imagedata');
|
||||
$target = $this->getMediaTarget($docPart, $rId);
|
||||
if (null !== $target) {
|
||||
if ($this->hasImageLoading() && null !== $target) {
|
||||
if ('External' == $this->getTargetMode($docPart, $rId)) {
|
||||
$imageSource = $target;
|
||||
} else {
|
||||
@@ -271,7 +386,7 @@ abstract class AbstractPart
|
||||
$embedId = $xmlReader->getAttribute('r:embed', $node, 'wp:anchor/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip');
|
||||
}
|
||||
$target = $this->getMediaTarget($docPart, $embedId);
|
||||
if (null !== $target) {
|
||||
if ($this->hasImageLoading() && null !== $target) {
|
||||
$imageSource = "zip://{$this->docFile}#{$target}";
|
||||
$parent->addImage($imageSource, null, false, $name);
|
||||
}
|
||||
@@ -320,9 +435,12 @@ abstract class AbstractPart
|
||||
$type = ($runParent->nodeName == 'w:del') ? TrackChange::DELETED : TrackChange::INSERTED;
|
||||
$author = $runParent->getAttribute('w:author');
|
||||
$date = DateTime::createFromFormat('Y-m-d\TH:i:s\Z', $runParent->getAttribute('w:date'));
|
||||
$date = $date instanceof DateTime ? $date : null;
|
||||
$element->setChangeInfo($type, $author, $date);
|
||||
}
|
||||
}
|
||||
} elseif ($node->nodeName == 'w:softHyphen') {
|
||||
$element = $parent->addText("\u{200c}", $fontStyle, $paragraphStyle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,9 +482,8 @@ abstract class AbstractPart
|
||||
} elseif ('w:tc' == $rowNode->nodeName) { // Cell
|
||||
$cellWidth = $xmlReader->getAttribute('w:w', $rowNode, 'w:tcPr/w:tcW');
|
||||
$cellStyle = null;
|
||||
$cellStyleNode = $xmlReader->getElement('w:tcPr', $rowNode);
|
||||
if (null !== $cellStyleNode) {
|
||||
$cellStyle = $this->readCellStyle($xmlReader, $cellStyleNode);
|
||||
if ($xmlReader->elementExists('w:tcPr', $rowNode)) {
|
||||
$cellStyle = $this->readCellStyle($xmlReader, $rowNode);
|
||||
}
|
||||
|
||||
$cell = $row->addCell($cellWidth, $cellStyle);
|
||||
@@ -374,6 +491,8 @@ abstract class AbstractPart
|
||||
foreach ($cellNodes as $cellNode) {
|
||||
if ('w:p' == $cellNode->nodeName) { // Paragraph
|
||||
$this->readParagraph($xmlReader, $cellNode, $cell, $docPart);
|
||||
} elseif ($cellNode->nodeName == 'w:tbl') { // Table
|
||||
$this->readTable($xmlReader, $cellNode, $cell, $docPart);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -550,7 +669,7 @@ abstract class AbstractPart
|
||||
/**
|
||||
* Read w:tcPr.
|
||||
*
|
||||
* @return array
|
||||
* @return null|array
|
||||
*/
|
||||
private function readCellStyle(XMLReader $xmlReader, DOMElement $domNode)
|
||||
{
|
||||
@@ -558,11 +677,28 @@ abstract class AbstractPart
|
||||
'valign' => [self::READ_VALUE, 'w:vAlign'],
|
||||
'textDirection' => [self::READ_VALUE, 'w:textDirection'],
|
||||
'gridSpan' => [self::READ_VALUE, 'w:gridSpan'],
|
||||
'vMerge' => [self::READ_VALUE, 'w:vMerge'],
|
||||
'vMerge' => [self::READ_VALUE, 'w:vMerge', null, null, 'continue'],
|
||||
'bgColor' => [self::READ_VALUE, 'w:shd', 'w:fill'],
|
||||
'noWrap' => [self::READ_VALUE, 'w:noWrap', null, null, true],
|
||||
];
|
||||
$style = null;
|
||||
|
||||
return $this->readStyleDefs($xmlReader, $domNode, $styleDefs);
|
||||
if ($xmlReader->elementExists('w:tcPr', $domNode)) {
|
||||
$styleNode = $xmlReader->getElement('w:tcPr', $domNode);
|
||||
|
||||
$borders = ['top', 'left', 'bottom', 'right'];
|
||||
foreach ($borders as $side) {
|
||||
$ucfSide = ucfirst($side);
|
||||
|
||||
$styleDefs['border' . $ucfSide . 'Size'] = [self::READ_VALUE, 'w:tcBorders/w:' . $side, 'w:sz'];
|
||||
$styleDefs['border' . $ucfSide . 'Color'] = [self::READ_VALUE, 'w:tcBorders/w:' . $side, 'w:color'];
|
||||
$styleDefs['border' . $ucfSide . 'Style'] = [self::READ_VALUE, 'w:tcBorders/w:' . $side, 'w:val'];
|
||||
}
|
||||
|
||||
$style = $this->readStyleDefs($xmlReader, $styleNode, $styleDefs);
|
||||
}
|
||||
|
||||
return $style;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -614,7 +750,6 @@ abstract class AbstractPart
|
||||
/**
|
||||
* Read style definition.
|
||||
*
|
||||
* @param DOMElement $parentNode
|
||||
* @param array $styleDefs
|
||||
*
|
||||
* @ignoreScrutinizerPatch
|
||||
@@ -626,7 +761,7 @@ abstract class AbstractPart
|
||||
$styles = [];
|
||||
|
||||
foreach ($styleDefs as $styleProp => $styleVal) {
|
||||
[$method, $element, $attribute, $expected] = array_pad($styleVal, 4, null);
|
||||
[$method, $element, $attribute, $expected, $default] = array_pad($styleVal, 5, null);
|
||||
|
||||
$element = $this->findPossibleElement($xmlReader, $parentNode, $element);
|
||||
if ($element === null) {
|
||||
@@ -640,7 +775,7 @@ abstract class AbstractPart
|
||||
|
||||
// Use w:val as default if no attribute assigned
|
||||
$attribute = ($attribute === null) ? 'w:val' : $attribute;
|
||||
$attributeValue = $xmlReader->getAttribute($attribute, $node);
|
||||
$attributeValue = $xmlReader->getAttribute($attribute, $node) ?? $default;
|
||||
|
||||
$styleValue = $this->readStyleDef($method, $attributeValue, $expected);
|
||||
if ($styleValue !== null) {
|
||||
|
||||
56
vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Comments.php
vendored
Normal file
56
vendor/phpoffice/phpword/src/PhpWord/Reader/Word2007/Comments.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpWord\Reader\Word2007;
|
||||
|
||||
use DateTime;
|
||||
use PhpOffice\PhpWord\Element\Comment;
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\Shared\XMLReader;
|
||||
|
||||
class Comments extends AbstractPart
|
||||
{
|
||||
/**
|
||||
* Collection name comments.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $collection = 'comments';
|
||||
|
||||
/**
|
||||
* Read settings.xml.
|
||||
*/
|
||||
public function read(PhpWord $phpWord): void
|
||||
{
|
||||
$xmlReader = new XMLReader();
|
||||
$xmlReader->getDomFromZip($this->docFile, $this->xmlFile);
|
||||
|
||||
$comments = $phpWord->getComments();
|
||||
|
||||
$nodes = $xmlReader->getElements('*');
|
||||
|
||||
foreach ($nodes as $node) {
|
||||
$name = str_replace('w:', '', $node->nodeName);
|
||||
|
||||
$author = $xmlReader->getAttribute('w:author', $node);
|
||||
$date = $xmlReader->getAttribute('w:date', $node);
|
||||
$initials = $xmlReader->getAttribute('w:initials', $node);
|
||||
|
||||
$element = new Comment($author, new DateTime($date), $initials);
|
||||
|
||||
$range = $this->getCommentReference($xmlReader->getAttribute('w:id', $node));
|
||||
if ($range['start']) {
|
||||
$range['start']->setCommentRangeStart($element);
|
||||
}
|
||||
if ($range['end']) {
|
||||
$range['end']->setCommentRangeEnd($element);
|
||||
}
|
||||
|
||||
$pNodes = $xmlReader->getElements('w:p/w:r', $node);
|
||||
foreach ($pNodes as $pNode) {
|
||||
$this->readRun($xmlReader, $pNode, $element, $this->collection);
|
||||
}
|
||||
|
||||
$phpWord->getComments()->addItem($element);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,10 @@ use PhpOffice\PhpWord\Style\Language;
|
||||
*/
|
||||
class Settings extends AbstractPart
|
||||
{
|
||||
private static $booleanProperties = [
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
private $booleanProperties = [
|
||||
'mirrorMargins',
|
||||
'hideSpellingErrors',
|
||||
'hideGrammaticalErrors',
|
||||
@@ -41,6 +44,7 @@ class Settings extends AbstractPart
|
||||
'updateFields',
|
||||
'autoHyphenation',
|
||||
'doNotHyphenateCaps',
|
||||
'bookFoldPrinting',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -60,12 +64,8 @@ class Settings extends AbstractPart
|
||||
$value = $xmlReader->getAttribute('w:val', $node);
|
||||
$method = 'set' . $name;
|
||||
|
||||
if (in_array($name, $this::$booleanProperties)) {
|
||||
if ($value == 'false') {
|
||||
$docSettings->$method(false);
|
||||
} else {
|
||||
$docSettings->$method(true);
|
||||
}
|
||||
if (in_array($name, $this->booleanProperties)) {
|
||||
$docSettings->$method($value !== 'false');
|
||||
} elseif (method_exists($this, $method)) {
|
||||
$this->$method($xmlReader, $phpWord, $node);
|
||||
} elseif (method_exists($docSettings, $method)) {
|
||||
|
||||
@@ -39,14 +39,16 @@ class Styles extends AbstractPart
|
||||
$fontDefaults = $xmlReader->getElement('w:docDefaults/w:rPrDefault');
|
||||
if ($fontDefaults !== null) {
|
||||
$fontDefaultStyle = $this->readFontStyle($xmlReader, $fontDefaults);
|
||||
if (array_key_exists('name', $fontDefaultStyle)) {
|
||||
$phpWord->setDefaultFontName($fontDefaultStyle['name']);
|
||||
}
|
||||
if (array_key_exists('size', $fontDefaultStyle)) {
|
||||
$phpWord->setDefaultFontSize($fontDefaultStyle['size']);
|
||||
}
|
||||
if (array_key_exists('lang', $fontDefaultStyle)) {
|
||||
$phpWord->getSettings()->setThemeFontLang(new Language($fontDefaultStyle['lang']));
|
||||
if ($fontDefaultStyle) {
|
||||
if (array_key_exists('name', $fontDefaultStyle)) {
|
||||
$phpWord->setDefaultFontName($fontDefaultStyle['name']);
|
||||
}
|
||||
if (array_key_exists('size', $fontDefaultStyle)) {
|
||||
$phpWord->setDefaultFontSize($fontDefaultStyle['size']);
|
||||
}
|
||||
if (array_key_exists('lang', $fontDefaultStyle)) {
|
||||
$phpWord->getSettings()->setThemeFontLang(new Language($fontDefaultStyle['lang']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
212
vendor/phpoffice/phpword/src/PhpWord/Settings.php
vendored
212
vendor/phpoffice/phpword/src/PhpWord/Settings.php
vendored
@@ -2,10 +2,8 @@
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
@@ -29,48 +27,46 @@ class Settings
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
const ZIPARCHIVE = 'ZipArchive';
|
||||
const PCLZIP = 'PclZip';
|
||||
const OLD_LIB = \PhpOffice\PhpWord\Shared\ZipArchive::class; // @deprecated 0.11
|
||||
public const ZIPARCHIVE = 'ZipArchive';
|
||||
public const PCLZIP = 'PclZip';
|
||||
public const OLD_LIB = \PhpOffice\PhpWord\Shared\ZipArchive::class; // @deprecated 0.11
|
||||
|
||||
/**
|
||||
* PDF rendering libraries.
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
const PDF_RENDERER_DOMPDF = 'DomPDF';
|
||||
const PDF_RENDERER_TCPDF = 'TCPDF';
|
||||
const PDF_RENDERER_MPDF = 'MPDF';
|
||||
public const PDF_RENDERER_DOMPDF = 'DomPDF';
|
||||
public const PDF_RENDERER_TCPDF = 'TCPDF';
|
||||
public const PDF_RENDERER_MPDF = 'MPDF';
|
||||
|
||||
/**
|
||||
* Measurement units multiplication factor.
|
||||
*
|
||||
* Applied to:
|
||||
* - Section: margins, header/footer height, gutter, column spacing
|
||||
* - Tab: position
|
||||
* - Indentation: left, right, firstLine, hanging
|
||||
* - Spacing: before, after
|
||||
* - Spacing: before, after.
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
const UNIT_TWIP = 'twip'; // = 1/20 point
|
||||
const UNIT_CM = 'cm';
|
||||
const UNIT_MM = 'mm';
|
||||
const UNIT_INCH = 'inch';
|
||||
const UNIT_POINT = 'point'; // = 1/72 inch
|
||||
const UNIT_PICA = 'pica'; // = 1/6 inch = 12 points
|
||||
public const UNIT_TWIP = 'twip'; // = 1/20 point
|
||||
public const UNIT_CM = 'cm';
|
||||
public const UNIT_MM = 'mm';
|
||||
public const UNIT_INCH = 'inch';
|
||||
public const UNIT_POINT = 'point'; // = 1/72 inch
|
||||
public const UNIT_PICA = 'pica'; // = 1/6 inch = 12 points
|
||||
|
||||
/**
|
||||
* Default font settings.
|
||||
*
|
||||
* OOXML defined font size values in halfpoints, i.e. twice of what PhpWord
|
||||
* use, and the conversion will be conducted during XML writing.
|
||||
*/
|
||||
const DEFAULT_FONT_NAME = 'Arial';
|
||||
const DEFAULT_FONT_SIZE = 10;
|
||||
const DEFAULT_FONT_COLOR = '000000';
|
||||
const DEFAULT_FONT_CONTENT_TYPE = 'default'; // default|eastAsia|cs
|
||||
const DEFAULT_PAPER = 'A4';
|
||||
public const DEFAULT_FONT_NAME = 'Arial';
|
||||
public const DEFAULT_FONT_SIZE = 10;
|
||||
public const DEFAULT_FONT_COLOR = '000000';
|
||||
public const DEFAULT_FONT_CONTENT_TYPE = 'default'; // default|eastAsia|cs
|
||||
public const DEFAULT_PAPER = 'A4';
|
||||
|
||||
/**
|
||||
* Compatibility option for XMLWriter.
|
||||
@@ -89,21 +85,28 @@ class Settings
|
||||
/**
|
||||
* Name of the external Library used for rendering PDF files.
|
||||
*
|
||||
* @var string
|
||||
* @var null|string
|
||||
*/
|
||||
private static $pdfRendererName;
|
||||
|
||||
/**
|
||||
* Options used for rendering PDF files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $pdfRendererOptions = [];
|
||||
|
||||
/**
|
||||
* Directory Path to the external Library used for rendering PDF files.
|
||||
*
|
||||
* @var string
|
||||
* @var null|string
|
||||
*/
|
||||
private static $pdfRendererPath;
|
||||
|
||||
/**
|
||||
* Measurement unit.
|
||||
*
|
||||
* @var float|int
|
||||
* @var string
|
||||
*/
|
||||
private static $measurementUnit = self::UNIT_TWIP;
|
||||
|
||||
@@ -117,7 +120,7 @@ class Settings
|
||||
/**
|
||||
* Default font size.
|
||||
*
|
||||
* @var int
|
||||
* @var float|int
|
||||
*/
|
||||
private static $defaultFontSize = self::DEFAULT_FONT_SIZE;
|
||||
|
||||
@@ -128,6 +131,13 @@ class Settings
|
||||
*/
|
||||
private static $defaultPaper = self::DEFAULT_PAPER;
|
||||
|
||||
/**
|
||||
* Is RTL by default ?
|
||||
*
|
||||
* @var ?bool
|
||||
*/
|
||||
private static $defaultRtl;
|
||||
|
||||
/**
|
||||
* The user defined temporary directory.
|
||||
*
|
||||
@@ -148,23 +158,17 @@ class Settings
|
||||
*
|
||||
* @return bool Compatibility
|
||||
*/
|
||||
public static function hasCompatibility()
|
||||
public static function hasCompatibility(): bool
|
||||
{
|
||||
return self::$xmlWriterCompatibility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the compatibility option used by the XMLWriter.
|
||||
*
|
||||
* This sets the setIndent and setIndentString for better compatibility
|
||||
*
|
||||
* @param bool $compatibility
|
||||
*
|
||||
* @return bool
|
||||
* This sets the setIndent and setIndentString for better compatibility.
|
||||
*/
|
||||
public static function setCompatibility($compatibility)
|
||||
public static function setCompatibility(bool $compatibility): bool
|
||||
{
|
||||
$compatibility = (bool) $compatibility;
|
||||
self::$xmlWriterCompatibility = $compatibility;
|
||||
|
||||
return true;
|
||||
@@ -172,22 +176,16 @@ class Settings
|
||||
|
||||
/**
|
||||
* Get zip handler class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getZipClass()
|
||||
public static function getZipClass(): string
|
||||
{
|
||||
return self::$zipClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set zip handler class.
|
||||
*
|
||||
* @param string $zipClass
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function setZipClass($zipClass)
|
||||
public static function setZipClass(string $zipClass): bool
|
||||
{
|
||||
if (in_array($zipClass, [self::PCLZIP, self::ZIPARCHIVE, self::OLD_LIB])) {
|
||||
self::$zipClass = $zipClass;
|
||||
@@ -201,12 +199,9 @@ class Settings
|
||||
/**
|
||||
* Set details of the external library for rendering PDF files.
|
||||
*
|
||||
* @param string $libraryName
|
||||
* @param string $libraryBaseDir
|
||||
*
|
||||
* @return bool Success or failure
|
||||
*/
|
||||
public static function setPdfRenderer($libraryName, $libraryBaseDir)
|
||||
public static function setPdfRenderer(string $libraryName, string $libraryBaseDir): bool
|
||||
{
|
||||
if (!self::setPdfRendererName($libraryName)) {
|
||||
return false;
|
||||
@@ -217,22 +212,16 @@ class Settings
|
||||
|
||||
/**
|
||||
* Return the PDF Rendering Library.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getPdfRendererName()
|
||||
public static function getPdfRendererName(): ?string
|
||||
{
|
||||
return self::$pdfRendererName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify the external library to use for rendering PDF files.
|
||||
*
|
||||
* @param string $libraryName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function setPdfRendererName($libraryName)
|
||||
public static function setPdfRendererName(?string $libraryName): bool
|
||||
{
|
||||
$pdfRenderers = [self::PDF_RENDERER_DOMPDF, self::PDF_RENDERER_TCPDF, self::PDF_RENDERER_MPDF];
|
||||
if (!in_array($libraryName, $pdfRenderers)) {
|
||||
@@ -245,22 +234,36 @@ class Settings
|
||||
|
||||
/**
|
||||
* Return the directory path to the PDF Rendering Library.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getPdfRendererPath()
|
||||
public static function getPdfRendererPath(): ?string
|
||||
{
|
||||
return self::$pdfRendererPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set options of the external library for rendering PDF files.
|
||||
*/
|
||||
public static function setPdfRendererOptions(array $options): void
|
||||
{
|
||||
self::$pdfRendererOptions = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the PDF Rendering Options.
|
||||
*/
|
||||
public static function getPdfRendererOptions(): array
|
||||
{
|
||||
return self::$pdfRendererOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Location of external library to use for rendering PDF files.
|
||||
*
|
||||
* @param string $libraryBaseDir Directory path to the library's base folder
|
||||
* @param null|string $libraryBaseDir Directory path to the library's base folder
|
||||
*
|
||||
* @return bool Success or failure
|
||||
*/
|
||||
public static function setPdfRendererPath($libraryBaseDir)
|
||||
public static function setPdfRendererPath(?string $libraryBaseDir): bool
|
||||
{
|
||||
if (!$libraryBaseDir || false === file_exists($libraryBaseDir) || false === is_readable($libraryBaseDir)) {
|
||||
return false;
|
||||
@@ -272,25 +275,25 @@ class Settings
|
||||
|
||||
/**
|
||||
* Get measurement unit.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getMeasurementUnit()
|
||||
public static function getMeasurementUnit(): string
|
||||
{
|
||||
return self::$measurementUnit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set measurement unit.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function setMeasurementUnit($value)
|
||||
public static function setMeasurementUnit(string $value): bool
|
||||
{
|
||||
$units = [self::UNIT_TWIP, self::UNIT_CM, self::UNIT_MM, self::UNIT_INCH,
|
||||
self::UNIT_POINT, self::UNIT_PICA, ];
|
||||
$units = [
|
||||
self::UNIT_TWIP,
|
||||
self::UNIT_CM,
|
||||
self::UNIT_MM,
|
||||
self::UNIT_INCH,
|
||||
self::UNIT_POINT,
|
||||
self::UNIT_PICA,
|
||||
];
|
||||
if (!in_array($value, $units)) {
|
||||
return false;
|
||||
}
|
||||
@@ -302,11 +305,11 @@ class Settings
|
||||
/**
|
||||
* Sets the user defined path to temporary directory.
|
||||
*
|
||||
* @since 0.12.0
|
||||
*
|
||||
* @param string $tempDir The user defined path to temporary directory
|
||||
*
|
||||
* @since 0.12.0
|
||||
*/
|
||||
public static function setTempDir($tempDir): void
|
||||
public static function setTempDir(string $tempDir): void
|
||||
{
|
||||
self::$tempDir = $tempDir;
|
||||
}
|
||||
@@ -315,10 +318,8 @@ class Settings
|
||||
* Returns path to temporary directory.
|
||||
*
|
||||
* @since 0.12.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getTempDir()
|
||||
public static function getTempDir(): string
|
||||
{
|
||||
if (!empty(self::$tempDir)) {
|
||||
$tempDir = self::$tempDir;
|
||||
@@ -331,44 +332,34 @@ class Settings
|
||||
|
||||
/**
|
||||
* @since 0.13.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isOutputEscapingEnabled()
|
||||
public static function isOutputEscapingEnabled(): bool
|
||||
{
|
||||
return self::$outputEscapingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.13.0
|
||||
*
|
||||
* @param bool $outputEscapingEnabled
|
||||
*/
|
||||
public static function setOutputEscapingEnabled($outputEscapingEnabled): void
|
||||
public static function setOutputEscapingEnabled(bool $outputEscapingEnabled): void
|
||||
{
|
||||
self::$outputEscapingEnabled = $outputEscapingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default font name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getDefaultFontName()
|
||||
public static function getDefaultFontName(): string
|
||||
{
|
||||
return self::$defaultFontName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default font name.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function setDefaultFontName($value)
|
||||
public static function setDefaultFontName(string $value): bool
|
||||
{
|
||||
if (is_string($value) && trim($value) !== '') {
|
||||
if (trim($value) !== '') {
|
||||
self::$defaultFontName = $value;
|
||||
|
||||
return true;
|
||||
@@ -380,7 +371,7 @@ class Settings
|
||||
/**
|
||||
* Get default font size.
|
||||
*
|
||||
* @return int
|
||||
* @return float|int
|
||||
*/
|
||||
public static function getDefaultFontSize()
|
||||
{
|
||||
@@ -390,14 +381,11 @@ class Settings
|
||||
/**
|
||||
* Set default font size.
|
||||
*
|
||||
* @param int $value
|
||||
*
|
||||
* @return bool
|
||||
* @param null|float|int $value
|
||||
*/
|
||||
public static function setDefaultFontSize($value)
|
||||
public static function setDefaultFontSize($value): bool
|
||||
{
|
||||
$value = (int) $value;
|
||||
if ($value > 0) {
|
||||
if ((is_int($value) || is_float($value)) && (int) $value > 0) {
|
||||
self::$defaultFontSize = $value;
|
||||
|
||||
return true;
|
||||
@@ -406,14 +394,20 @@ class Settings
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function setDefaultRtl(?bool $defaultRtl): void
|
||||
{
|
||||
self::$defaultRtl = $defaultRtl;
|
||||
}
|
||||
|
||||
public static function isDefaultRtl(): ?bool
|
||||
{
|
||||
return self::$defaultRtl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load setting from phpword.yml or phpword.yml.dist.
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function loadConfig($filename = null)
|
||||
public static function loadConfig(?string $filename = null): array
|
||||
{
|
||||
// Get config file
|
||||
$configFile = null;
|
||||
@@ -455,24 +449,18 @@ class Settings
|
||||
|
||||
/**
|
||||
* Get default paper.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getDefaultPaper()
|
||||
public static function getDefaultPaper(): string
|
||||
{
|
||||
return self::$defaultPaper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default paper.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function setDefaultPaper($value)
|
||||
public static function setDefaultPaper(string $value): bool
|
||||
{
|
||||
if (is_string($value) && trim($value) !== '') {
|
||||
if (trim($value) !== '') {
|
||||
self::$defaultPaper = $value;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -374,7 +374,7 @@ class Converter
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return float
|
||||
* @return ?float
|
||||
*/
|
||||
public static function cssToPoint($value)
|
||||
{
|
||||
|
||||
80
vendor/phpoffice/phpword/src/PhpWord/Shared/Css.php
vendored
Normal file
80
vendor/phpoffice/phpword/src/PhpWord/Shared/Css.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
*
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpWord\Shared;
|
||||
|
||||
class Css
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cssContent;
|
||||
|
||||
/**
|
||||
* @var array<string, array<string, string>>
|
||||
*/
|
||||
private $styles = [];
|
||||
|
||||
public function __construct(string $cssContent)
|
||||
{
|
||||
$this->cssContent = $cssContent;
|
||||
}
|
||||
|
||||
public function process(): void
|
||||
{
|
||||
$cssContent = str_replace(["\r", "\n"], '', $this->cssContent);
|
||||
preg_match_all('/(.+?)\s?\{\s?(.+?)\s?\}/', $cssContent, $cssExtracted);
|
||||
// Check the number of extracted
|
||||
if (count($cssExtracted) != 3) {
|
||||
return;
|
||||
}
|
||||
// Check if there are x selectors and x rules
|
||||
if (count($cssExtracted[1]) != count($cssExtracted[2])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($cssExtracted[1] as $key => $selector) {
|
||||
$rules = trim($cssExtracted[2][$key]);
|
||||
$rules = explode(';', $rules);
|
||||
foreach ($rules as $rule) {
|
||||
if (empty($rule)) {
|
||||
continue;
|
||||
}
|
||||
[$key, $value] = explode(':', trim($rule));
|
||||
$this->styles[$this->sanitize($selector)][$this->sanitize($key)] = $this->sanitize($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getStyles(): array
|
||||
{
|
||||
return $this->styles;
|
||||
}
|
||||
|
||||
public function getStyle(string $selector): array
|
||||
{
|
||||
$selector = $this->sanitize($selector);
|
||||
|
||||
return $this->styles[$selector] ?? [];
|
||||
}
|
||||
|
||||
private function sanitize(string $value): string
|
||||
{
|
||||
return addslashes(trim($value));
|
||||
}
|
||||
}
|
||||
158
vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php
vendored
158
vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php
vendored
@@ -43,6 +43,11 @@ class Html
|
||||
|
||||
protected static $options;
|
||||
|
||||
/**
|
||||
* @var Css
|
||||
*/
|
||||
protected static $css;
|
||||
|
||||
/**
|
||||
* Add HTML parts.
|
||||
*
|
||||
@@ -61,7 +66,7 @@ class Html
|
||||
* @todo parse $stylesheet for default styles. Should result in an array based on id, class and element,
|
||||
* which could be applied when such an element occurs in the parseNode function.
|
||||
*/
|
||||
self::$options = $options;
|
||||
static::$options = $options;
|
||||
|
||||
// Preprocess: remove all line ends, decode HTML entity,
|
||||
// fix ampersand and angle brackets and add body tag for HTML fragments
|
||||
@@ -82,10 +87,10 @@ class Html
|
||||
$dom = new DOMDocument();
|
||||
$dom->preserveWhiteSpace = $preserveWhiteSpace;
|
||||
$dom->loadXML($html);
|
||||
self::$xpath = new DOMXPath($dom);
|
||||
static::$xpath = new DOMXPath($dom);
|
||||
$node = $dom->getElementsByTagName('body');
|
||||
|
||||
self::parseNode($node->item(0), $element);
|
||||
static::parseNode($node->item(0), $element);
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
libxml_disable_entity_loader($orignalLibEntityLoader);
|
||||
}
|
||||
@@ -104,11 +109,12 @@ class Html
|
||||
if (XML_ELEMENT_NODE == $node->nodeType) {
|
||||
$attributes = $node->attributes; // get all the attributes(eg: id, class)
|
||||
|
||||
$bidi = ($attributes['dir'] ?? '') === 'rtl';
|
||||
foreach ($attributes as $attribute) {
|
||||
$val = $attribute->value;
|
||||
switch (strtolower($attribute->name)) {
|
||||
case 'align':
|
||||
$styles['alignment'] = self::mapAlign(trim($val));
|
||||
$styles['alignment'] = self::mapAlign(trim($val), $bidi);
|
||||
|
||||
break;
|
||||
case 'lang':
|
||||
@@ -149,6 +155,19 @@ class Html
|
||||
}
|
||||
}
|
||||
|
||||
$attributeIdentifier = $attributes->getNamedItem('id');
|
||||
if ($attributeIdentifier && self::$css) {
|
||||
$styles = self::parseStyleDeclarations(self::$css->getStyle('#' . $attributeIdentifier->value), $styles);
|
||||
}
|
||||
|
||||
$attributeClass = $attributes->getNamedItem('class');
|
||||
if ($attributeClass) {
|
||||
if (self::$css) {
|
||||
$styles = self::parseStyleDeclarations(self::$css->getStyle('.' . $attributeClass->value), $styles);
|
||||
}
|
||||
$styles['className'] = $attributeClass->value;
|
||||
}
|
||||
|
||||
$attributeStyle = $attributes->getNamedItem('style');
|
||||
if ($attributeStyle) {
|
||||
$styles = self::parseStyle($attributeStyle, $styles);
|
||||
@@ -168,6 +187,13 @@ class Html
|
||||
*/
|
||||
protected static function parseNode($node, $element, $styles = [], $data = []): void
|
||||
{
|
||||
if ($node->nodeName == 'style') {
|
||||
self::$css = new Css($node->textContent);
|
||||
self::$css->process();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Populate styles array
|
||||
$styleTypes = ['font', 'paragraph', 'list', 'table', 'row', 'cell'];
|
||||
foreach ($styleTypes as $styleType) {
|
||||
@@ -246,7 +272,7 @@ class Html
|
||||
* Parse child nodes.
|
||||
*
|
||||
* @param DOMNode $node
|
||||
* @param \PhpOffice\PhpWord\Element\AbstractContainer $element
|
||||
* @param \PhpOffice\PhpWord\Element\AbstractContainer|Row|Table $element
|
||||
* @param array $styles
|
||||
* @param array $data
|
||||
*/
|
||||
@@ -389,6 +415,11 @@ class Html
|
||||
|
||||
$newElement = $element->addTable($elementStyles);
|
||||
|
||||
// Add style name from CSS Class
|
||||
if (isset($elementStyles['className'])) {
|
||||
$newElement->getStyle()->setStyleName($elementStyles['className']);
|
||||
}
|
||||
|
||||
$attributes = $node->attributes;
|
||||
if ($attributes->getNamedItem('border') !== null) {
|
||||
$border = (int) $attributes->getNamedItem('border')->value;
|
||||
@@ -414,7 +445,11 @@ class Html
|
||||
$rowStyles['tblHeader'] = true;
|
||||
}
|
||||
|
||||
return $element->addRow(null, $rowStyles);
|
||||
// set cell height to control row heights
|
||||
$height = $rowStyles['height'] ?? null;
|
||||
unset($rowStyles['height']); // would not apply
|
||||
|
||||
return $element->addRow($height, $rowStyles);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -635,13 +670,22 @@ class Html
|
||||
{
|
||||
$properties = explode(';', trim($attribute->value, " \t\n\r\0\x0B;"));
|
||||
|
||||
$selectors = [];
|
||||
foreach ($properties as $property) {
|
||||
[$cKey, $cValue] = array_pad(explode(':', $property, 2), 2, null);
|
||||
$cValue = trim($cValue ?? '');
|
||||
$cKey = strtolower(trim($cKey));
|
||||
switch ($cKey) {
|
||||
$selectors[strtolower(trim($cKey))] = trim($cValue ?? '');
|
||||
}
|
||||
|
||||
return self::parseStyleDeclarations($selectors, $styles);
|
||||
}
|
||||
|
||||
protected static function parseStyleDeclarations(array $selectors, array $styles)
|
||||
{
|
||||
$bidi = ($selectors['direction'] ?? '') === 'rtl';
|
||||
foreach ($selectors as $property => $value) {
|
||||
switch ($property) {
|
||||
case 'text-decoration':
|
||||
switch ($cValue) {
|
||||
switch ($value) {
|
||||
case 'underline':
|
||||
$styles['underline'] = 'single';
|
||||
|
||||
@@ -654,44 +698,45 @@ class Html
|
||||
|
||||
break;
|
||||
case 'text-align':
|
||||
$styles['alignment'] = self::mapAlign($cValue);
|
||||
$styles['alignment'] = self::mapAlign($value, $bidi);
|
||||
|
||||
break;
|
||||
case 'display':
|
||||
$styles['hidden'] = $cValue === 'none' || $cValue === 'hidden';
|
||||
$styles['hidden'] = $value === 'none' || $value === 'hidden';
|
||||
|
||||
break;
|
||||
case 'direction':
|
||||
$styles['rtl'] = $cValue === 'rtl';
|
||||
$styles['rtl'] = $value === 'rtl';
|
||||
$styles['bidi'] = $value === 'rtl';
|
||||
|
||||
break;
|
||||
case 'font-size':
|
||||
$styles['size'] = Converter::cssToPoint($cValue);
|
||||
$styles['size'] = Converter::cssToPoint($value);
|
||||
|
||||
break;
|
||||
case 'font-family':
|
||||
$cValue = array_map('trim', explode(',', $cValue));
|
||||
$styles['name'] = ucwords($cValue[0]);
|
||||
$value = array_map('trim', explode(',', $value));
|
||||
$styles['name'] = ucwords($value[0]);
|
||||
|
||||
break;
|
||||
case 'color':
|
||||
$styles['color'] = trim($cValue, '#');
|
||||
$styles['color'] = trim($value, '#');
|
||||
|
||||
break;
|
||||
case 'background-color':
|
||||
$styles['bgColor'] = trim($cValue, '#');
|
||||
$styles['bgColor'] = trim($value, '#');
|
||||
|
||||
break;
|
||||
case 'line-height':
|
||||
$matches = [];
|
||||
if ($cValue === 'normal') {
|
||||
if ($value === 'normal') {
|
||||
$spacingLineRule = \PhpOffice\PhpWord\SimpleType\LineSpacingRule::AUTO;
|
||||
$spacing = 0;
|
||||
} elseif (preg_match('/([0-9]+\.?[0-9]*[a-z]+)/', $cValue, $matches)) {
|
||||
} elseif (preg_match('/([0-9]+\.?[0-9]*[a-z]+)/', $value, $matches)) {
|
||||
//matches number with a unit, e.g. 12px, 15pt, 20mm, ...
|
||||
$spacingLineRule = \PhpOffice\PhpWord\SimpleType\LineSpacingRule::EXACT;
|
||||
$spacing = Converter::cssToTwip($matches[1]);
|
||||
} elseif (preg_match('/([0-9]+)%/', $cValue, $matches)) {
|
||||
} elseif (preg_match('/([0-9]+)%/', $value, $matches)) {
|
||||
//matches percentages
|
||||
$spacingLineRule = \PhpOffice\PhpWord\SimpleType\LineSpacingRule::AUTO;
|
||||
//we are subtracting 1 line height because the Spacing writer is adding one line
|
||||
@@ -700,23 +745,23 @@ class Html
|
||||
//any other, wich is a multiplier. E.g. 1.2
|
||||
$spacingLineRule = \PhpOffice\PhpWord\SimpleType\LineSpacingRule::AUTO;
|
||||
//we are subtracting 1 line height because the Spacing writer is adding one line
|
||||
$spacing = ($cValue * Paragraph::LINE_HEIGHT) - Paragraph::LINE_HEIGHT;
|
||||
$spacing = ($value * Paragraph::LINE_HEIGHT) - Paragraph::LINE_HEIGHT;
|
||||
}
|
||||
$styles['spacingLineRule'] = $spacingLineRule;
|
||||
$styles['line-spacing'] = $spacing;
|
||||
|
||||
break;
|
||||
case 'letter-spacing':
|
||||
$styles['letter-spacing'] = Converter::cssToTwip($cValue);
|
||||
$styles['letter-spacing'] = Converter::cssToTwip($value);
|
||||
|
||||
break;
|
||||
case 'text-indent':
|
||||
$styles['indentation']['firstLine'] = Converter::cssToTwip($cValue);
|
||||
$styles['indentation']['firstLine'] = Converter::cssToTwip($value);
|
||||
|
||||
break;
|
||||
case 'font-weight':
|
||||
$tValue = false;
|
||||
if (preg_match('#bold#', $cValue)) {
|
||||
if (preg_match('#bold#', $value)) {
|
||||
$tValue = true; // also match bolder
|
||||
}
|
||||
$styles['bold'] = $tValue;
|
||||
@@ -724,52 +769,65 @@ class Html
|
||||
break;
|
||||
case 'font-style':
|
||||
$tValue = false;
|
||||
if (preg_match('#(?:italic|oblique)#', $cValue)) {
|
||||
if (preg_match('#(?:italic|oblique)#', $value)) {
|
||||
$tValue = true;
|
||||
}
|
||||
$styles['italic'] = $tValue;
|
||||
|
||||
break;
|
||||
case 'font-variant':
|
||||
$tValue = false;
|
||||
if (preg_match('#small-caps#', $value)) {
|
||||
$tValue = true;
|
||||
}
|
||||
$styles['smallCaps'] = $tValue;
|
||||
|
||||
break;
|
||||
case 'margin':
|
||||
$cValue = Converter::cssToTwip($cValue);
|
||||
$styles['spaceBefore'] = $cValue;
|
||||
$styles['spaceAfter'] = $cValue;
|
||||
$value = Converter::cssToTwip($value);
|
||||
$styles['spaceBefore'] = $value;
|
||||
$styles['spaceAfter'] = $value;
|
||||
|
||||
break;
|
||||
case 'margin-top':
|
||||
// BC change: up to ver. 0.17.0 incorrectly converted to points - Converter::cssToPoint($cValue)
|
||||
$styles['spaceBefore'] = Converter::cssToTwip($cValue);
|
||||
// BC change: up to ver. 0.17.0 incorrectly converted to points - Converter::cssToPoint($value)
|
||||
$styles['spaceBefore'] = Converter::cssToTwip($value);
|
||||
|
||||
break;
|
||||
case 'margin-bottom':
|
||||
// BC change: up to ver. 0.17.0 incorrectly converted to points - Converter::cssToPoint($cValue)
|
||||
$styles['spaceAfter'] = Converter::cssToTwip($cValue);
|
||||
// BC change: up to ver. 0.17.0 incorrectly converted to points - Converter::cssToPoint($value)
|
||||
$styles['spaceAfter'] = Converter::cssToTwip($value);
|
||||
|
||||
break;
|
||||
case 'border-color':
|
||||
self::mapBorderColor($styles, $cValue);
|
||||
self::mapBorderColor($styles, $value);
|
||||
|
||||
break;
|
||||
case 'border-width':
|
||||
$styles['borderSize'] = Converter::cssToPoint($cValue);
|
||||
$styles['borderSize'] = Converter::cssToPoint($value);
|
||||
|
||||
break;
|
||||
case 'border-style':
|
||||
$styles['borderStyle'] = self::mapBorderStyle($cValue);
|
||||
$styles['borderStyle'] = self::mapBorderStyle($value);
|
||||
|
||||
break;
|
||||
case 'width':
|
||||
if (preg_match('/([0-9]+[a-z]+)/', $cValue, $matches)) {
|
||||
if (preg_match('/([0-9]+[a-z]+)/', $value, $matches)) {
|
||||
$styles['width'] = Converter::cssToTwip($matches[1]);
|
||||
$styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::TWIP;
|
||||
} elseif (preg_match('/([0-9]+)%/', $cValue, $matches)) {
|
||||
} elseif (preg_match('/([0-9]+)%/', $value, $matches)) {
|
||||
$styles['width'] = $matches[1] * 50;
|
||||
$styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::PERCENT;
|
||||
} elseif (preg_match('/([0-9]+)/', $cValue, $matches)) {
|
||||
} elseif (preg_match('/([0-9]+)/', $value, $matches)) {
|
||||
$styles['width'] = $matches[1];
|
||||
$styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::AUTO;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'height':
|
||||
$styles['height'] = Converter::cssToTwip($value);
|
||||
$styles['exactHeight'] = true;
|
||||
|
||||
break;
|
||||
case 'border':
|
||||
case 'border-top':
|
||||
@@ -778,9 +836,9 @@ class Html
|
||||
case 'border-left':
|
||||
// must have exact order [width color style], e.g. "1px #0011CC solid" or "2pt green solid"
|
||||
// Word does not accept shortened hex colors e.g. #CCC, only full e.g. #CCCCCC
|
||||
if (preg_match('/([0-9]+[^0-9]*)\s+(\#[a-fA-F0-9]+|[a-zA-Z]+)\s+([a-z]+)/', $cValue, $matches)) {
|
||||
if (false !== strpos($cKey, '-')) {
|
||||
$tmp = explode('-', $cKey);
|
||||
if (preg_match('/([0-9]+[^0-9]*)\s+(\#[a-fA-F0-9]+|[a-zA-Z]+)\s+([a-z]+)/', $value, $matches)) {
|
||||
if (false !== strpos($property, '-')) {
|
||||
$tmp = explode('-', $property);
|
||||
$which = $tmp[1];
|
||||
$which = ucfirst($which); // e.g. bottom -> Bottom
|
||||
} else {
|
||||
@@ -803,13 +861,13 @@ class Html
|
||||
break;
|
||||
case 'vertical-align':
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align
|
||||
if (preg_match('#(?:top|bottom|middle|sub|baseline)#i', $cValue, $matches)) {
|
||||
if (preg_match('#(?:top|bottom|middle|sub|baseline)#i', $value, $matches)) {
|
||||
$styles['valign'] = self::mapAlignVertical($matches[0]);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'page-break-after':
|
||||
if ($cValue == 'always') {
|
||||
if ($value == 'always') {
|
||||
$styles['isPageBreak'] = true;
|
||||
}
|
||||
|
||||
@@ -910,7 +968,10 @@ class Html
|
||||
$tmpDir = Settings::getTempDir() . '/';
|
||||
$match = [];
|
||||
preg_match('/.+\.(\w+)$/', $src, $match);
|
||||
$src = $tmpDir . uniqid() . '.' . $match[1];
|
||||
$src = $tmpDir . uniqid();
|
||||
if (isset($match[1])) {
|
||||
$src .= '.' . $match[1];
|
||||
}
|
||||
|
||||
$ifp = fopen($src, 'wb');
|
||||
|
||||
@@ -968,20 +1029,21 @@ class Html
|
||||
* Transforms a HTML/CSS alignment into a \PhpOffice\PhpWord\SimpleType\Jc.
|
||||
*
|
||||
* @param string $cssAlignment
|
||||
* @param bool $bidi
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected static function mapAlign($cssAlignment)
|
||||
protected static function mapAlign($cssAlignment, $bidi)
|
||||
{
|
||||
switch ($cssAlignment) {
|
||||
case 'right':
|
||||
return Jc::END;
|
||||
return $bidi ? Jc::START : Jc::END;
|
||||
case 'center':
|
||||
return Jc::CENTER;
|
||||
case 'justify':
|
||||
return Jc::BOTH;
|
||||
default:
|
||||
return Jc::START;
|
||||
return $bidi ? Jc::END : Jc::START;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,17 @@ class OLERead
|
||||
public $wrkObjectPool = null;
|
||||
public $summaryInformation = null;
|
||||
public $docSummaryInfos = null;
|
||||
public $numBigBlockDepotBlocks = null;
|
||||
public $rootStartBlock = null;
|
||||
public $sbdStartBlock = null;
|
||||
public $extensionBlock = null;
|
||||
public $numExtensionBlocks = null;
|
||||
public $bigBlockChain = null;
|
||||
public $smallBlockChain = null;
|
||||
public $entry = null;
|
||||
public $rootentry = null;
|
||||
public $wrkObjectPoolelseif = null;
|
||||
public $props = array();
|
||||
|
||||
/**
|
||||
* Read the file
|
||||
|
||||
@@ -1597,7 +1597,7 @@ class PclZip
|
||||
if (is_string($p_options_list[$i + 1])) {
|
||||
|
||||
// ----- Remove spaces
|
||||
$p_options_list[$i + 1] = strtr($p_options_list[$i + 1], ' ', '');
|
||||
$p_options_list[$i + 1] = str_replace(' ', '', $p_options_list[$i + 1]);
|
||||
|
||||
// ----- Parse items
|
||||
$v_work_list = explode(",", $p_options_list[$i + 1]);
|
||||
|
||||
@@ -138,14 +138,15 @@ class Text
|
||||
/**
|
||||
* Return UTF8 encoded value.
|
||||
*
|
||||
* @param string $value
|
||||
* @param null|string $value
|
||||
*
|
||||
* @return string
|
||||
* @return ?string
|
||||
*/
|
||||
public static function toUTF8($value = '')
|
||||
{
|
||||
if (null !== $value && !self::isUTF8($value)) {
|
||||
$value = utf8_encode($value);
|
||||
// PHP8.2 : utf8_encode is deprecated, but mb_convert_encoding always usable
|
||||
$value = (function_exists('mb_convert_encoding')) ? mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1') : utf8_encode($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
76
vendor/phpoffice/phpword/src/PhpWord/Shared/Validate.php
vendored
Normal file
76
vendor/phpoffice/phpword/src/PhpWord/Shared/Validate.php
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
*
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpWord\Shared;
|
||||
|
||||
class Validate
|
||||
{
|
||||
public const CSS_WHITESPACE = [
|
||||
'pre-wrap',
|
||||
'normal',
|
||||
'nowrap',
|
||||
'pre',
|
||||
'pre-line',
|
||||
'initial',
|
||||
'inherit',
|
||||
];
|
||||
|
||||
public const CSS_GENERICFONT = [
|
||||
'serif',
|
||||
'sans-serif',
|
||||
'monospace',
|
||||
'cursive',
|
||||
'fantasy',
|
||||
'system-ui',
|
||||
'math',
|
||||
'emoji',
|
||||
'fangsong',
|
||||
];
|
||||
|
||||
/**
|
||||
* Validate html css white-space value. It is expected that only pre-wrap and normal (default) are useful.
|
||||
*
|
||||
* @param string $value CSS White space
|
||||
*
|
||||
* @return string value if valid, empty string if not
|
||||
*/
|
||||
public static function validateCSSWhiteSpace(?string $value): string
|
||||
{
|
||||
if (in_array($value, self::CSS_WHITESPACE)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate generic font for fallback for html.
|
||||
*
|
||||
* @param string $value Generic font name
|
||||
*
|
||||
* @return string Value if legitimate, empty string if not
|
||||
*/
|
||||
public static function validateCSSGenericFont(?string $value): string
|
||||
{
|
||||
if (in_array($value, self::CSS_GENERICFONT)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ class XMLReader
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($zipFile);
|
||||
$content = $zip->getFromName($xmlFile);
|
||||
$content = $zip->getFromName(ltrim($xmlFile, '/'));
|
||||
$zip->close();
|
||||
|
||||
if ($content === false) {
|
||||
@@ -97,24 +97,21 @@ class XMLReader
|
||||
* Get elements.
|
||||
*
|
||||
* @param string $path
|
||||
* @param DOMElement $contextNode
|
||||
*
|
||||
* @return DOMNodeList
|
||||
* @return DOMNodeList<DOMElement>
|
||||
*/
|
||||
public function getElements($path, ?DOMElement $contextNode = null)
|
||||
{
|
||||
if ($this->dom === null) {
|
||||
return [];
|
||||
return new DOMNodeList(); // @phpstan-ignore-line
|
||||
}
|
||||
if ($this->xpath === null) {
|
||||
$this->xpath = new DOMXpath($this->dom);
|
||||
}
|
||||
|
||||
if (null === $contextNode) {
|
||||
return $this->xpath->query($path);
|
||||
}
|
||||
$result = @$this->xpath->query($path, $contextNode);
|
||||
|
||||
return $this->xpath->query($path, $contextNode);
|
||||
return empty($result) ? new DOMNodeList() : $result; // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +138,6 @@ class XMLReader
|
||||
* Get element.
|
||||
*
|
||||
* @param string $path
|
||||
* @param DOMElement $contextNode
|
||||
*
|
||||
* @return null|DOMElement
|
||||
*/
|
||||
@@ -159,7 +155,6 @@ class XMLReader
|
||||
* Get element attribute.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param DOMElement $contextNode
|
||||
* @param string $path
|
||||
*
|
||||
* @return null|string
|
||||
@@ -187,7 +182,6 @@ class XMLReader
|
||||
* Get element value.
|
||||
*
|
||||
* @param string $path
|
||||
* @param DOMElement $contextNode
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
@@ -205,7 +199,6 @@ class XMLReader
|
||||
* Count elements.
|
||||
*
|
||||
* @param string $path
|
||||
* @param DOMElement $contextNode
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -220,7 +213,6 @@ class XMLReader
|
||||
* Element exists.
|
||||
*
|
||||
* @param string $path
|
||||
* @param DOMElement $contextNode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
@@ -30,8 +30,8 @@ use PhpOffice\PhpWord\Settings;
|
||||
*
|
||||
* @method bool addFile(string $filename, string $localname = null)
|
||||
* @method bool addFromString(string $localname, string $contents)
|
||||
* @method string getNameIndex(int $index)
|
||||
* @method int locateName(string $name)
|
||||
* @method false|string getNameIndex(int $index)
|
||||
* @method false|int locateName(string $name)
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
@@ -396,7 +396,7 @@ class ZipArchive
|
||||
*
|
||||
* @param string $filename Filename for the file in zip archive
|
||||
*
|
||||
* @return int
|
||||
* @return false|int
|
||||
*/
|
||||
public function pclzipLocateName($filename)
|
||||
{
|
||||
|
||||
26
vendor/phpoffice/phpword/src/PhpWord/Style.php
vendored
26
vendor/phpoffice/phpword/src/PhpWord/Style.php
vendored
@@ -39,7 +39,7 @@ class Style
|
||||
* Add paragraph style.
|
||||
*
|
||||
* @param string $styleName
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles
|
||||
* @param AbstractStyle|array $styles
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Paragraph
|
||||
*/
|
||||
@@ -52,8 +52,8 @@ class Style
|
||||
* Add font style.
|
||||
*
|
||||
* @param string $styleName
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $fontStyle
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $paragraphStyle
|
||||
* @param AbstractStyle|array $fontStyle
|
||||
* @param AbstractStyle|array $paragraphStyle
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Font
|
||||
*/
|
||||
@@ -66,7 +66,7 @@ class Style
|
||||
* Add link style.
|
||||
*
|
||||
* @param string $styleName
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles
|
||||
* @param AbstractStyle|array $styles
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Font
|
||||
*/
|
||||
@@ -79,7 +79,7 @@ class Style
|
||||
* Add numbering style.
|
||||
*
|
||||
* @param string $styleName
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styleValues
|
||||
* @param AbstractStyle|array $styleValues
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Numbering
|
||||
*
|
||||
@@ -94,8 +94,8 @@ class Style
|
||||
* Add title style.
|
||||
*
|
||||
* @param null|int $depth Provide null to set title font
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $fontStyle
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $paragraphStyle
|
||||
* @param AbstractStyle|array $fontStyle
|
||||
* @param AbstractStyle|array $paragraphStyle
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Font
|
||||
*/
|
||||
@@ -149,7 +149,7 @@ class Style
|
||||
/**
|
||||
* Set default paragraph style.
|
||||
*
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles Paragraph style definition
|
||||
* @param AbstractStyle|array $styles Paragraph style definition
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Paragraph
|
||||
*/
|
||||
@@ -161,7 +161,7 @@ class Style
|
||||
/**
|
||||
* Get all styles.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\AbstractStyle[]
|
||||
* @return AbstractStyle[]
|
||||
*/
|
||||
public static function getStyles()
|
||||
{
|
||||
@@ -173,7 +173,7 @@ class Style
|
||||
*
|
||||
* @param string $styleName
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\AbstractStyle Paragraph|Font|Table|Numbering
|
||||
* @return ?AbstractStyle Paragraph|Font|Table|Numbering
|
||||
*/
|
||||
public static function getStyle($styleName)
|
||||
{
|
||||
@@ -190,10 +190,10 @@ class Style
|
||||
* The $styleValues could be an array or object
|
||||
*
|
||||
* @param string $name
|
||||
* @param \PhpOffice\PhpWord\Style\AbstractStyle $style
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $value
|
||||
* @param AbstractStyle $style
|
||||
* @param AbstractStyle|array $value
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\AbstractStyle
|
||||
* @return AbstractStyle
|
||||
*/
|
||||
private static function setStyleValues($name, $style, $value = null)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ abstract class AbstractStyle
|
||||
/**
|
||||
* Style name.
|
||||
*
|
||||
* @var string
|
||||
* @var ?string
|
||||
*/
|
||||
protected $styleName;
|
||||
|
||||
@@ -62,7 +62,7 @@ abstract class AbstractStyle
|
||||
/**
|
||||
* Get style name.
|
||||
*
|
||||
* @return string
|
||||
* @return ?string
|
||||
*/
|
||||
public function getStyleName()
|
||||
{
|
||||
@@ -161,7 +161,7 @@ abstract class AbstractStyle
|
||||
* Check if the set method is exists. Throws an exception?
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @param array|int|string $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
@@ -202,10 +202,10 @@ abstract class AbstractStyle
|
||||
/**
|
||||
* Set default for null and empty value.
|
||||
*
|
||||
* @param string $value (was: mixed)
|
||||
* @param string $default (was: mixed)
|
||||
* @param ?string $value
|
||||
* @param string $default
|
||||
*
|
||||
* @return string (was: mixed)
|
||||
* @return string
|
||||
*/
|
||||
protected function setNonEmptyVal($value, $default)
|
||||
{
|
||||
@@ -253,7 +253,7 @@ abstract class AbstractStyle
|
||||
/**
|
||||
* Set integer value: Convert string that contains only numeric into integer.
|
||||
*
|
||||
* @param null|int $value
|
||||
* @param null|float|int|string $value
|
||||
* @param null|int $default
|
||||
*
|
||||
* @return null|int
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace PhpOffice\PhpWord\Style;
|
||||
*/
|
||||
class Border extends AbstractStyle
|
||||
{
|
||||
const DEFAULT_MARGIN = 1440; // In twips.
|
||||
|
||||
/**
|
||||
* Border Top Size.
|
||||
*
|
||||
@@ -106,6 +108,34 @@ class Border extends AbstractStyle
|
||||
*/
|
||||
protected $borderBottomStyle;
|
||||
|
||||
/**
|
||||
* Top margin spacing.
|
||||
*
|
||||
* @var float|int
|
||||
*/
|
||||
protected $marginTop = self::DEFAULT_MARGIN;
|
||||
|
||||
/**
|
||||
* Left margin spacing.
|
||||
*
|
||||
* @var float|int
|
||||
*/
|
||||
protected $marginLeft = self::DEFAULT_MARGIN;
|
||||
|
||||
/**
|
||||
* Right margin spacing.
|
||||
*
|
||||
* @var float|int
|
||||
*/
|
||||
protected $marginRight = self::DEFAULT_MARGIN;
|
||||
|
||||
/**
|
||||
* Bottom margin spacing.
|
||||
*
|
||||
* @var float|int
|
||||
*/
|
||||
protected $marginBottom = self::DEFAULT_MARGIN;
|
||||
|
||||
/**
|
||||
* Get border size.
|
||||
*
|
||||
@@ -501,4 +531,100 @@ class Border extends AbstractStyle
|
||||
|
||||
return $borders !== array_filter($borders, 'is_null');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Margin Top.
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function getMarginTop()
|
||||
{
|
||||
return $this->marginTop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Margin Top.
|
||||
*
|
||||
* @param float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setMarginTop($value = null)
|
||||
{
|
||||
$this->marginTop = $this->setNumericVal($value, self::DEFAULT_MARGIN);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Margin Left.
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function getMarginLeft()
|
||||
{
|
||||
return $this->marginLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Margin Left.
|
||||
*
|
||||
* @param float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setMarginLeft($value = null)
|
||||
{
|
||||
$this->marginLeft = $this->setNumericVal($value, self::DEFAULT_MARGIN);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Margin Right.
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function getMarginRight()
|
||||
{
|
||||
return $this->marginRight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Margin Right.
|
||||
*
|
||||
* @param float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setMarginRight($value = null)
|
||||
{
|
||||
$this->marginRight = $this->setNumericVal($value, self::DEFAULT_MARGIN);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Margin Bottom.
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function getMarginBottom()
|
||||
{
|
||||
return $this->marginBottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Margin Bottom.
|
||||
*
|
||||
* @param float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setMarginBottom($value = null)
|
||||
{
|
||||
$this->marginBottom = $this->setNumericVal($value, self::DEFAULT_MARGIN);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ class Cell extends Border
|
||||
/**
|
||||
* Width.
|
||||
*
|
||||
* @var int
|
||||
* @var ?int
|
||||
*/
|
||||
private $width;
|
||||
|
||||
@@ -118,6 +118,13 @@ class Cell extends Border
|
||||
*/
|
||||
private $unit = TblWidth::TWIP;
|
||||
|
||||
/**
|
||||
* Prevent text from wrapping in the cell.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $noWrap = true;
|
||||
|
||||
/**
|
||||
* Get vertical align.
|
||||
*
|
||||
@@ -162,7 +169,14 @@ class Cell extends Border
|
||||
*/
|
||||
public function setTextDirection($value = null)
|
||||
{
|
||||
$enum = [self::TEXT_DIR_BTLR, self::TEXT_DIR_TBRL];
|
||||
$enum = [
|
||||
self::TEXT_DIR_BTLR,
|
||||
self::TEXT_DIR_TBRL,
|
||||
self::TEXT_DIR_LRTB,
|
||||
self::TEXT_DIR_LRTBV,
|
||||
self::TEXT_DIR_TBRLV,
|
||||
self::TEXT_DIR_TBLRV,
|
||||
];
|
||||
$this->textDirection = $this->setEnumVal($value, $enum, $this->textDirection);
|
||||
|
||||
return $this;
|
||||
@@ -270,7 +284,7 @@ class Cell extends Border
|
||||
/**
|
||||
* Get cell width.
|
||||
*
|
||||
* @return int
|
||||
* @return ?int
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
@@ -286,7 +300,7 @@ class Cell extends Border
|
||||
*/
|
||||
public function setWidth($value)
|
||||
{
|
||||
$this->setIntVal($value);
|
||||
$this->width = $this->setIntVal($value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -312,4 +326,22 @@ class Cell extends Border
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set noWrap.
|
||||
*/
|
||||
public function setNoWrap(bool $value): self
|
||||
{
|
||||
$this->noWrap = $this->setBoolVal($value, true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get noWrap.
|
||||
*/
|
||||
public function getNoWrap(): bool
|
||||
{
|
||||
return $this->noWrap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Style;
|
||||
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Shared\Validate;
|
||||
|
||||
/**
|
||||
* Font style.
|
||||
*/
|
||||
@@ -230,7 +233,7 @@ class Font extends AbstractStyle
|
||||
/**
|
||||
* Right to left languages.
|
||||
*
|
||||
* @var bool
|
||||
* @var ?bool
|
||||
*/
|
||||
private $rtl;
|
||||
|
||||
@@ -245,7 +248,7 @@ class Font extends AbstractStyle
|
||||
/**
|
||||
* Languages.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Language
|
||||
* @var null|\PhpOffice\PhpWord\Style\Language
|
||||
*/
|
||||
private $lang;
|
||||
|
||||
@@ -267,6 +270,20 @@ class Font extends AbstractStyle
|
||||
*/
|
||||
private $position;
|
||||
|
||||
/**
|
||||
* Preservation of white space in html.
|
||||
*
|
||||
* @var string Value used for css white-space
|
||||
*/
|
||||
private $whiteSpace = '';
|
||||
|
||||
/**
|
||||
* Generic font as fallback for html.
|
||||
*
|
||||
* @var string generic font name
|
||||
*/
|
||||
private $fallbackFont = '';
|
||||
|
||||
/**
|
||||
* Create new font style.
|
||||
*
|
||||
@@ -288,7 +305,7 @@ class Font extends AbstractStyle
|
||||
*/
|
||||
public function getStyleValues()
|
||||
{
|
||||
$styles = [
|
||||
return [
|
||||
'name' => $this->getStyleName(),
|
||||
'basic' => [
|
||||
'name' => $this->getName(),
|
||||
@@ -319,9 +336,9 @@ class Font extends AbstractStyle
|
||||
'rtl' => $this->isRTL(),
|
||||
'shading' => $this->getShading(),
|
||||
'lang' => $this->getLang(),
|
||||
'whiteSpace' => $this->getWhiteSpace(),
|
||||
'fallbackFont' => $this->getFallbackFont(),
|
||||
];
|
||||
|
||||
return $styles;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -827,17 +844,17 @@ class Font extends AbstractStyle
|
||||
/**
|
||||
* Get rtl.
|
||||
*
|
||||
* @return bool
|
||||
* @return ?bool
|
||||
*/
|
||||
public function isRTL()
|
||||
{
|
||||
return $this->rtl;
|
||||
return $this->rtl ?? Settings::isDefaultRtl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rtl.
|
||||
*
|
||||
* @param bool $value
|
||||
* @param ?bool $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
@@ -875,7 +892,7 @@ class Font extends AbstractStyle
|
||||
/**
|
||||
* Get language.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Language
|
||||
* @return null|\PhpOffice\PhpWord\Style\Language
|
||||
*/
|
||||
public function getLang()
|
||||
{
|
||||
@@ -946,4 +963,44 @@ class Font extends AbstractStyle
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set html css white-space value. It is expected that only pre-wrap and normal (default) are useful.
|
||||
*
|
||||
* @param null|string $value Should be one of pre-wrap, normal, nowrap, pre, pre-line, initial, inherit
|
||||
*/
|
||||
public function setWhiteSpace(?string $value): self
|
||||
{
|
||||
$this->whiteSpace = Validate::validateCSSWhiteSpace($value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get html css white-space value.
|
||||
*/
|
||||
public function getWhiteSpace(): string
|
||||
{
|
||||
return $this->whiteSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set generic font for fallback for html.
|
||||
*
|
||||
* @param string $value generic font name
|
||||
*/
|
||||
public function setFallbackFont(?string $value): self
|
||||
{
|
||||
$this->fallbackFont = Validate::validateCSSGenericFont($value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get html fallback generic font.
|
||||
*/
|
||||
public function getFallbackFont(): string
|
||||
{
|
||||
return $this->fallbackFont;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class Indentation extends AbstractStyle
|
||||
*
|
||||
* @var float|int
|
||||
*/
|
||||
private $firstLine;
|
||||
private $firstLine = 0;
|
||||
|
||||
/**
|
||||
* Indentation removed from first line (twip).
|
||||
@@ -80,7 +80,7 @@ class Indentation extends AbstractStyle
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setLeft($value = null)
|
||||
public function setLeft($value)
|
||||
{
|
||||
$this->left = $this->setNumericVal($value, $this->left);
|
||||
|
||||
@@ -104,7 +104,7 @@ class Indentation extends AbstractStyle
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setRight($value = null)
|
||||
public function setRight($value)
|
||||
{
|
||||
$this->right = $this->setNumericVal($value, $this->right);
|
||||
|
||||
@@ -128,7 +128,7 @@ class Indentation extends AbstractStyle
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setFirstLine($value = null)
|
||||
public function setFirstLine($value)
|
||||
{
|
||||
$this->firstLine = $this->setNumericVal($value, $this->firstLine);
|
||||
|
||||
|
||||
@@ -40,18 +40,27 @@ final class Language extends AbstractStyle
|
||||
const FR_BE = 'fr-BE';
|
||||
const FR_BE_ID = 2060;
|
||||
|
||||
const FR_CH = 'fr-CH';
|
||||
const FR_CH_ID = 4108;
|
||||
|
||||
const ES_ES = 'es-ES';
|
||||
const ES_ES_ID = 3082;
|
||||
|
||||
const DE_DE = 'de-DE';
|
||||
const DE_DE_ID = 1031;
|
||||
|
||||
const DE_CH = 'de-CH';
|
||||
const DE_CH_ID = 2055;
|
||||
|
||||
const HE_IL = 'he-IL';
|
||||
const HE_IL_ID = 1037;
|
||||
|
||||
const IT_IT = 'it-IT';
|
||||
const IT_IT_ID = 1040;
|
||||
|
||||
const IT_CH = 'it-CH';
|
||||
const IT_CH_ID = 2064;
|
||||
|
||||
const JA_JP = 'ja-JP';
|
||||
const JA_JP_ID = 1041;
|
||||
|
||||
@@ -70,6 +79,9 @@ final class Language extends AbstractStyle
|
||||
const NL_NL = 'nl-NL';
|
||||
const NL_NL_ID = 1043;
|
||||
|
||||
const SV_SE = 'sv-SE';
|
||||
const SV_SE_ID = 1053;
|
||||
|
||||
const UK_UA = 'uk-UA';
|
||||
const UK_UA_ID = 1058;
|
||||
|
||||
@@ -244,7 +256,9 @@ final class Language extends AbstractStyle
|
||||
if ($locale !== null && strlen($locale) === 2) {
|
||||
return strtolower($locale) . '-' . strtoupper($locale);
|
||||
}
|
||||
|
||||
if ($locale === 'und') {
|
||||
return 'en-EN';
|
||||
}
|
||||
if ($locale !== null && $locale !== 'zxx' && strstr($locale, '-') === false) {
|
||||
throw new InvalidArgumentException($locale . ' is not a valid language code');
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
namespace PhpOffice\PhpWord\Style;
|
||||
|
||||
use PhpOffice\PhpWord\Exception\InvalidStyleException;
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Shared\Text;
|
||||
use PhpOffice\PhpWord\SimpleType\Jc;
|
||||
use PhpOffice\PhpWord\SimpleType\TextAlignment;
|
||||
@@ -99,7 +100,7 @@ class Paragraph extends Border
|
||||
/**
|
||||
* Text line height.
|
||||
*
|
||||
* @var int
|
||||
* @var null|float|int
|
||||
*/
|
||||
private $lineHeight;
|
||||
|
||||
@@ -169,9 +170,9 @@ class Paragraph extends Border
|
||||
/**
|
||||
* Right to Left Paragraph Layout.
|
||||
*
|
||||
* @var bool
|
||||
* @var ?bool
|
||||
*/
|
||||
private $bidi = false;
|
||||
private $bidi;
|
||||
|
||||
/**
|
||||
* Vertical Character Alignment on Line.
|
||||
@@ -321,9 +322,9 @@ class Paragraph extends Border
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shading.
|
||||
* Get indentation.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Indentation
|
||||
* @return null|\PhpOffice\PhpWord\Style\Indentation
|
||||
*/
|
||||
public function getIndentation()
|
||||
{
|
||||
@@ -419,7 +420,7 @@ class Paragraph extends Border
|
||||
/**
|
||||
* Get space before paragraph.
|
||||
*
|
||||
* @return int
|
||||
* @return null|float|int
|
||||
*/
|
||||
public function getSpaceBefore()
|
||||
{
|
||||
@@ -429,7 +430,7 @@ class Paragraph extends Border
|
||||
/**
|
||||
* Set space before paragraph.
|
||||
*
|
||||
* @param int $value
|
||||
* @param null|float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
@@ -441,7 +442,7 @@ class Paragraph extends Border
|
||||
/**
|
||||
* Get space after paragraph.
|
||||
*
|
||||
* @return int
|
||||
* @return null|float|int
|
||||
*/
|
||||
public function getSpaceAfter()
|
||||
{
|
||||
@@ -451,7 +452,7 @@ class Paragraph extends Border
|
||||
/**
|
||||
* Set space after paragraph.
|
||||
*
|
||||
* @param int $value
|
||||
* @param null|float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
@@ -463,7 +464,7 @@ class Paragraph extends Border
|
||||
/**
|
||||
* Get spacing between lines.
|
||||
*
|
||||
* @return float|int
|
||||
* @return null|float|int
|
||||
*/
|
||||
public function getSpacing()
|
||||
{
|
||||
@@ -473,7 +474,7 @@ class Paragraph extends Border
|
||||
/**
|
||||
* Set spacing between lines.
|
||||
*
|
||||
* @param float|int $value
|
||||
* @param null|float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
@@ -507,7 +508,7 @@ class Paragraph extends Border
|
||||
/**
|
||||
* Get line height.
|
||||
*
|
||||
* @return float|int
|
||||
* @return null|float|int
|
||||
*/
|
||||
public function getLineHeight()
|
||||
{
|
||||
@@ -759,17 +760,17 @@ class Paragraph extends Border
|
||||
/**
|
||||
* Get bidirectional.
|
||||
*
|
||||
* @return bool
|
||||
* @return ?bool
|
||||
*/
|
||||
public function isBidi()
|
||||
{
|
||||
return $this->bidi;
|
||||
return $this->bidi ?? Settings::isDefaultRtl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bidi.
|
||||
*
|
||||
* @param bool $bidi
|
||||
* @param ?bool $bidi
|
||||
* Set to true to write from right to left
|
||||
*
|
||||
* @return self
|
||||
|
||||
@@ -40,7 +40,6 @@ class Section extends Border
|
||||
*/
|
||||
const DEFAULT_WIDTH = 11905.511811024; // In twips.
|
||||
const DEFAULT_HEIGHT = 16837.79527559; // In twips.
|
||||
const DEFAULT_MARGIN = 1440; // In twips.
|
||||
const DEFAULT_GUTTER = 0; // In twips.
|
||||
const DEFAULT_HEADER_HEIGHT = 720; // In twips.
|
||||
const DEFAULT_FOOTER_HEIGHT = 720; // In twips.
|
||||
@@ -77,34 +76,6 @@ class Section extends Border
|
||||
*/
|
||||
private $pageSizeH = self::DEFAULT_HEIGHT;
|
||||
|
||||
/**
|
||||
* Top margin spacing.
|
||||
*
|
||||
* @var float|int
|
||||
*/
|
||||
private $marginTop = self::DEFAULT_MARGIN;
|
||||
|
||||
/**
|
||||
* Left margin spacing.
|
||||
*
|
||||
* @var float|int
|
||||
*/
|
||||
private $marginLeft = self::DEFAULT_MARGIN;
|
||||
|
||||
/**
|
||||
* Right margin spacing.
|
||||
*
|
||||
* @var float|int
|
||||
*/
|
||||
private $marginRight = self::DEFAULT_MARGIN;
|
||||
|
||||
/**
|
||||
* Bottom margin spacing.
|
||||
*
|
||||
* @var float|int
|
||||
*/
|
||||
private $marginBottom = self::DEFAULT_MARGIN;
|
||||
|
||||
/**
|
||||
* Page gutter spacing.
|
||||
*
|
||||
@@ -159,7 +130,7 @@ class Section extends Border
|
||||
* - evenPage: Even page section break
|
||||
* - oddPage: Odd page section break
|
||||
*
|
||||
* @var string
|
||||
* @var ?string
|
||||
*/
|
||||
private $breakType;
|
||||
|
||||
@@ -176,7 +147,7 @@ class Section extends Border
|
||||
* Vertical Text Alignment on Page
|
||||
* One of \PhpOffice\PhpWord\SimpleType\VerticalJc.
|
||||
*
|
||||
* @var string
|
||||
* @var ?string
|
||||
*/
|
||||
private $vAlign;
|
||||
|
||||
@@ -224,7 +195,7 @@ class Section extends Border
|
||||
* Set Setting Value.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @param array|int|string $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
@@ -344,102 +315,6 @@ class Section extends Border
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Margin Top.
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function getMarginTop()
|
||||
{
|
||||
return $this->marginTop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Margin Top.
|
||||
*
|
||||
* @param float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setMarginTop($value = null)
|
||||
{
|
||||
$this->marginTop = $this->setNumericVal($value, self::DEFAULT_MARGIN);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Margin Left.
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function getMarginLeft()
|
||||
{
|
||||
return $this->marginLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Margin Left.
|
||||
*
|
||||
* @param float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setMarginLeft($value = null)
|
||||
{
|
||||
$this->marginLeft = $this->setNumericVal($value, self::DEFAULT_MARGIN);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Margin Right.
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function getMarginRight()
|
||||
{
|
||||
return $this->marginRight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Margin Right.
|
||||
*
|
||||
* @param float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setMarginRight($value = null)
|
||||
{
|
||||
$this->marginRight = $this->setNumericVal($value, self::DEFAULT_MARGIN);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Margin Bottom.
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function getMarginBottom()
|
||||
{
|
||||
return $this->marginBottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Margin Bottom.
|
||||
*
|
||||
* @param float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setMarginBottom($value = null)
|
||||
{
|
||||
$this->marginBottom = $this->setNumericVal($value, self::DEFAULT_MARGIN);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gutter.
|
||||
*
|
||||
@@ -587,7 +462,7 @@ class Section extends Border
|
||||
/**
|
||||
* Get Break Type.
|
||||
*
|
||||
* @return string
|
||||
* @return ?string
|
||||
*/
|
||||
public function getBreakType()
|
||||
{
|
||||
@@ -635,7 +510,7 @@ class Section extends Border
|
||||
/**
|
||||
* Get vertical alignment.
|
||||
*
|
||||
* @return string
|
||||
* @return ?string
|
||||
*/
|
||||
public function getVAlign()
|
||||
{
|
||||
|
||||
@@ -30,21 +30,21 @@ class Spacing extends AbstractStyle
|
||||
/**
|
||||
* Spacing above paragraph (twip).
|
||||
*
|
||||
* @var float|int
|
||||
* @var null|float|int
|
||||
*/
|
||||
private $before;
|
||||
|
||||
/**
|
||||
* Spacing below paragraph (twip).
|
||||
*
|
||||
* @var float|int
|
||||
* @var null|float|int
|
||||
*/
|
||||
private $after;
|
||||
|
||||
/**
|
||||
* Spacing between lines in paragraph (twip).
|
||||
*
|
||||
* @var float|int
|
||||
* @var null|float|int
|
||||
*/
|
||||
private $line;
|
||||
|
||||
@@ -68,7 +68,7 @@ class Spacing extends AbstractStyle
|
||||
/**
|
||||
* Get before.
|
||||
*
|
||||
* @return float|int
|
||||
* @return null|float|int
|
||||
*/
|
||||
public function getBefore()
|
||||
{
|
||||
@@ -78,7 +78,7 @@ class Spacing extends AbstractStyle
|
||||
/**
|
||||
* Set before.
|
||||
*
|
||||
* @param float|int $value
|
||||
* @param null|float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
@@ -92,7 +92,7 @@ class Spacing extends AbstractStyle
|
||||
/**
|
||||
* Get after.
|
||||
*
|
||||
* @return float|int
|
||||
* @return null|float|int
|
||||
*/
|
||||
public function getAfter()
|
||||
{
|
||||
@@ -102,7 +102,7 @@ class Spacing extends AbstractStyle
|
||||
/**
|
||||
* Set after.
|
||||
*
|
||||
* @param float|int $value
|
||||
* @param null|float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
@@ -116,7 +116,7 @@ class Spacing extends AbstractStyle
|
||||
/**
|
||||
* Get line.
|
||||
*
|
||||
* @return float|int
|
||||
* @return null|float|int
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
@@ -126,7 +126,7 @@ class Spacing extends AbstractStyle
|
||||
/**
|
||||
* Set distance.
|
||||
*
|
||||
* @param float|int $value
|
||||
* @param null|float|int $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
namespace PhpOffice\PhpWord\Style;
|
||||
|
||||
use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType;
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\SimpleType\Jc;
|
||||
use PhpOffice\PhpWord\SimpleType\JcTable;
|
||||
use PhpOffice\PhpWord\SimpleType\TblWidth;
|
||||
use PhpOffice\PhpWord\Style;
|
||||
|
||||
class Table extends Border
|
||||
{
|
||||
@@ -131,7 +133,7 @@ class Table extends Border
|
||||
private $unit = TblWidth::AUTO;
|
||||
|
||||
/**
|
||||
* @var float|int cell spacing value
|
||||
* @var null|float|int cell spacing value
|
||||
*/
|
||||
protected $cellSpacing;
|
||||
|
||||
@@ -143,7 +145,7 @@ class Table extends Border
|
||||
/**
|
||||
* Position.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\TablePosition
|
||||
* @var ?\PhpOffice\PhpWord\Style\TablePosition
|
||||
*/
|
||||
private $position;
|
||||
|
||||
@@ -162,9 +164,9 @@ class Table extends Border
|
||||
*
|
||||
* @see http://www.datypic.com/sc/ooxml/e-w_bidiVisual-1.html
|
||||
*
|
||||
* @var bool
|
||||
* @var ?bool
|
||||
*/
|
||||
private $bidiVisual = false;
|
||||
private $bidiVisual;
|
||||
|
||||
/**
|
||||
* Create new table style.
|
||||
@@ -188,7 +190,7 @@ class Table extends Border
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float|int $cellSpacing
|
||||
* @param null|float|int $cellSpacing
|
||||
*/
|
||||
public function setCellSpacing($cellSpacing = null): void
|
||||
{
|
||||
@@ -196,7 +198,7 @@ class Table extends Border
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float|int
|
||||
* @return null|float|int
|
||||
*/
|
||||
public function getCellSpacing()
|
||||
{
|
||||
@@ -216,7 +218,7 @@ class Table extends Border
|
||||
/**
|
||||
* Get background.
|
||||
*
|
||||
* @return string
|
||||
* @return ?string
|
||||
*/
|
||||
public function getBgColor()
|
||||
{
|
||||
@@ -704,7 +706,7 @@ class Table extends Border
|
||||
/**
|
||||
* Get position.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\TablePosition
|
||||
* @return ?\PhpOffice\PhpWord\Style\TablePosition
|
||||
*/
|
||||
public function getPosition()
|
||||
{
|
||||
@@ -726,7 +728,7 @@ class Table extends Border
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TblWidthComplexType
|
||||
* @return ?TblWidthComplexType
|
||||
*/
|
||||
public function getIndent()
|
||||
{
|
||||
@@ -768,17 +770,17 @@ class Table extends Border
|
||||
/**
|
||||
* Get bidiVisual.
|
||||
*
|
||||
* @return bool
|
||||
* @return ?bool
|
||||
*/
|
||||
public function isBidiVisual()
|
||||
{
|
||||
return $this->bidiVisual;
|
||||
return $this->bidiVisual ?? Settings::isDefaultRtl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bidiVisual.
|
||||
*
|
||||
* @param bool $bidi
|
||||
* @param ?bool $bidi
|
||||
* Set to true to visually present table as Right to Left
|
||||
*
|
||||
* @return self
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
@@ -27,121 +25,128 @@ class TextBox extends Image
|
||||
/**
|
||||
* margin top.
|
||||
*
|
||||
* @var int
|
||||
* @var null|int
|
||||
*/
|
||||
private $innerMarginTop;
|
||||
|
||||
/**
|
||||
* margin left.
|
||||
*
|
||||
* @var int
|
||||
* @var null|int
|
||||
*/
|
||||
private $innerMarginLeft;
|
||||
|
||||
/**
|
||||
* margin right.
|
||||
*
|
||||
* @var int
|
||||
* @var null|int
|
||||
*/
|
||||
private $innerMarginRight;
|
||||
|
||||
/**
|
||||
* Cell margin bottom.
|
||||
*
|
||||
* @var int
|
||||
* @var null|int
|
||||
*/
|
||||
private $innerMarginBottom;
|
||||
|
||||
/**
|
||||
* border size.
|
||||
*
|
||||
* @var int
|
||||
* @var null|int
|
||||
*/
|
||||
private $borderSize;
|
||||
|
||||
/**
|
||||
* border color.
|
||||
*
|
||||
* @var string
|
||||
* @var null|string
|
||||
*/
|
||||
private $borderColor;
|
||||
|
||||
/**
|
||||
* Set margin top.
|
||||
* background color.
|
||||
*
|
||||
* @param int $value
|
||||
* @var null|string
|
||||
*/
|
||||
public function setInnerMarginTop($value = null): void
|
||||
private $bgColor;
|
||||
|
||||
/**
|
||||
* Set background color.
|
||||
*/
|
||||
public function setBgColor(?string $value = null): void
|
||||
{
|
||||
$this->bgColor = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get background color.
|
||||
*/
|
||||
public function getBgColor(): ?string
|
||||
{
|
||||
return $this->bgColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set margin top.
|
||||
*/
|
||||
public function setInnerMarginTop(?int $value = null): void
|
||||
{
|
||||
$this->innerMarginTop = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get margin top.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getInnerMarginTop()
|
||||
public function getInnerMarginTop(): ?int
|
||||
{
|
||||
return $this->innerMarginTop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set margin left.
|
||||
*
|
||||
* @param int $value
|
||||
*/
|
||||
public function setInnerMarginLeft($value = null): void
|
||||
public function setInnerMarginLeft(?int $value = null): void
|
||||
{
|
||||
$this->innerMarginLeft = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get margin left.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getInnerMarginLeft()
|
||||
public function getInnerMarginLeft(): ?int
|
||||
{
|
||||
return $this->innerMarginLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set margin right.
|
||||
*
|
||||
* @param int $value
|
||||
*/
|
||||
public function setInnerMarginRight($value = null): void
|
||||
public function setInnerMarginRight(?int $value = null): void
|
||||
{
|
||||
$this->innerMarginRight = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get margin right.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getInnerMarginRight()
|
||||
public function getInnerMarginRight(): ?int
|
||||
{
|
||||
return $this->innerMarginRight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set margin bottom.
|
||||
*
|
||||
* @param int $value
|
||||
*/
|
||||
public function setInnerMarginBottom($value = null): void
|
||||
public function setInnerMarginBottom(?int $value = null): void
|
||||
{
|
||||
$this->innerMarginBottom = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get margin bottom.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getInnerMarginBottom()
|
||||
public function getInnerMarginBottom(): ?int
|
||||
{
|
||||
return $this->innerMarginBottom;
|
||||
}
|
||||
@@ -149,9 +154,9 @@ class TextBox extends Image
|
||||
/**
|
||||
* Set TLRB cell margin.
|
||||
*
|
||||
* @param int $value Margin in twips
|
||||
* @param null|int $value Margin in twips
|
||||
*/
|
||||
public function setInnerMargin($value = null): void
|
||||
public function setInnerMargin(?int $value = null): void
|
||||
{
|
||||
$this->setInnerMarginTop($value);
|
||||
$this->setInnerMarginLeft($value);
|
||||
@@ -164,17 +169,15 @@ class TextBox extends Image
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function getInnerMargin()
|
||||
public function getInnerMargin(): array
|
||||
{
|
||||
return [$this->innerMarginLeft, $this->innerMarginTop, $this->innerMarginRight, $this->innerMarginBottom];
|
||||
}
|
||||
|
||||
/**
|
||||
* Has inner margin?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasInnerMargins()
|
||||
public function hasInnerMargins(): bool
|
||||
{
|
||||
$hasInnerMargins = false;
|
||||
$margins = $this->getInnerMargin();
|
||||
@@ -191,39 +194,33 @@ class TextBox extends Image
|
||||
/**
|
||||
* Set border size.
|
||||
*
|
||||
* @param int $value Size in points
|
||||
* @param null|int $value Size in points
|
||||
*/
|
||||
public function setBorderSize($value = null): void
|
||||
public function setBorderSize(?int $value = null): void
|
||||
{
|
||||
$this->borderSize = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get border size.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getBorderSize()
|
||||
public function getBorderSize(): ?int
|
||||
{
|
||||
return $this->borderSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set border color.
|
||||
*
|
||||
* @param string $value
|
||||
*/
|
||||
public function setBorderColor($value = null): void
|
||||
public function setBorderColor(?string $value = null): void
|
||||
{
|
||||
$this->borderColor = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get border color.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBorderColor()
|
||||
public function getBorderColor(): ?string
|
||||
{
|
||||
return $this->borderColor;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ use PhpOffice\PhpWord\Exception\Exception;
|
||||
use PhpOffice\PhpWord\Shared\Text;
|
||||
use PhpOffice\PhpWord\Shared\XMLWriter;
|
||||
use PhpOffice\PhpWord\Shared\ZipArchive;
|
||||
use Throwable;
|
||||
use XSLTProcessor;
|
||||
|
||||
class TemplateProcessor
|
||||
@@ -94,6 +95,10 @@ class TemplateProcessor
|
||||
*/
|
||||
protected $tempDocumentNewImages = [];
|
||||
|
||||
protected static $macroOpeningChars = '${';
|
||||
|
||||
protected static $macroClosingChars = '}';
|
||||
|
||||
/**
|
||||
* @since 0.12.0 Throws CreateTemporaryFileException and CopyFileException instead of Exception
|
||||
*
|
||||
@@ -131,6 +136,30 @@ class TemplateProcessor
|
||||
$this->tempDocumentContentTypes = $this->zipClass->getFromName($this->getDocumentContentTypesName());
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
// ZipClass
|
||||
if ($this->zipClass) {
|
||||
try {
|
||||
$this->zipClass->close();
|
||||
} catch (Throwable $e) {
|
||||
// Nothing to do here.
|
||||
}
|
||||
}
|
||||
// Temporary file
|
||||
if ($this->tempDocumentFilename && file_exists($this->tempDocumentFilename)) {
|
||||
unlink($this->tempDocumentFilename);
|
||||
}
|
||||
}
|
||||
|
||||
public function __wakeup(): void
|
||||
{
|
||||
$this->tempDocumentFilename = '';
|
||||
$this->zipClass = null;
|
||||
|
||||
throw new Exception('unserialize not permitted for this class');
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose zip class.
|
||||
*
|
||||
@@ -238,30 +267,25 @@ class TemplateProcessor
|
||||
*/
|
||||
protected static function ensureMacroCompleted($macro)
|
||||
{
|
||||
if (substr($macro, 0, 2) !== '${' && substr($macro, -1) !== '}') {
|
||||
$macro = '${' . $macro . '}';
|
||||
if (substr($macro, 0, 2) !== self::$macroOpeningChars && substr($macro, -1) !== self::$macroClosingChars) {
|
||||
$macro = self::$macroOpeningChars . $macro . self::$macroClosingChars;
|
||||
}
|
||||
|
||||
return $macro;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $subject
|
||||
* @param ?string $subject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function ensureUtf8Encoded($subject)
|
||||
{
|
||||
if (!Text::isUTF8($subject) && null !== $subject) {
|
||||
$subject = utf8_encode($subject);
|
||||
}
|
||||
|
||||
return (null !== $subject) ? $subject : '';
|
||||
return $subject ? Text::toUTF8($subject) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param \PhpOffice\PhpWord\Element\AbstractElement $complexType
|
||||
*/
|
||||
public function setComplexValue($search, Element\AbstractElement $complexType): void
|
||||
{
|
||||
@@ -289,7 +313,6 @@ class TemplateProcessor
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param \PhpOffice\PhpWord\Element\AbstractElement $complexType
|
||||
*/
|
||||
public function setComplexBlock($search, Element\AbstractElement $complexType): void
|
||||
{
|
||||
@@ -349,6 +372,27 @@ class TemplateProcessor
|
||||
}
|
||||
}
|
||||
|
||||
public function setCheckbox(string $search, bool $checked): void
|
||||
{
|
||||
$search = static::ensureMacroCompleted($search);
|
||||
$blockType = 'w:sdt';
|
||||
|
||||
$where = $this->findContainingXmlBlockForMacro($search, $blockType);
|
||||
if (!is_array($where)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$block = $this->getSlice($where['start'], $where['end']);
|
||||
|
||||
$val = $checked ? '1' : '0';
|
||||
$block = preg_replace('/(<w14:checked w14:val=)".*?"(\/>)/', '$1"' . $val . '"$2', $block);
|
||||
|
||||
$text = $checked ? '☒' : '☐';
|
||||
$block = preg_replace('/(<w:t>).*?(<\/w:t>)/', '$1' . $text . '$2', $block);
|
||||
|
||||
$this->replaceXmlBlock($search, $block, $blockType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
*/
|
||||
@@ -433,7 +477,7 @@ class TemplateProcessor
|
||||
if (null === $value && isset($inlineValue)) {
|
||||
$value = $inlineValue;
|
||||
}
|
||||
if (!preg_match('/^([0-9]*(cm|mm|in|pt|pc|px|%|em|ex|)|auto)$/i', $value ?? '')) {
|
||||
if (!preg_match('/^([0-9\.]*(cm|mm|in|pt|pc|px|%|em|ex|)|auto)$/i', $value ?? '')) {
|
||||
$value = null;
|
||||
}
|
||||
if (null === $value) {
|
||||
@@ -759,6 +803,70 @@ class TemplateProcessor
|
||||
$this->tempDocumentMainPart = $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a table row in a template document.
|
||||
*/
|
||||
public function deleteRow(string $search): void
|
||||
{
|
||||
if ('${' !== substr($search, 0, 2) && '}' !== substr($search, -1)) {
|
||||
$search = '${' . $search . '}';
|
||||
}
|
||||
|
||||
$tagPos = strpos($this->tempDocumentMainPart, $search);
|
||||
if (!$tagPos) {
|
||||
throw new Exception(sprintf('Can not delete row %s, template variable not found or variable contains markup.', $search));
|
||||
}
|
||||
|
||||
$tableStart = $this->findTableStart($tagPos);
|
||||
$tableEnd = $this->findTableEnd($tagPos);
|
||||
$xmlTable = $this->getSlice($tableStart, $tableEnd);
|
||||
|
||||
if (substr_count($xmlTable, '<w:tr') === 1) {
|
||||
$this->tempDocumentMainPart = $this->getSlice(0, $tableStart) . $this->getSlice($tableEnd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$rowStart = $this->findRowStart($tagPos);
|
||||
$rowEnd = $this->findRowEnd($tagPos);
|
||||
$xmlRow = $this->getSlice($rowStart, $rowEnd);
|
||||
|
||||
$this->tempDocumentMainPart = $this->getSlice(0, $rowStart) . $this->getSlice($rowEnd);
|
||||
|
||||
// Check if there's a cell spanning multiple rows.
|
||||
if (preg_match('#<w:vMerge w:val="restart"/>#', $xmlRow)) {
|
||||
$extraRowStart = $rowStart;
|
||||
while (true) {
|
||||
$extraRowStart = $this->findRowStart($extraRowStart + 1);
|
||||
$extraRowEnd = $this->findRowEnd($extraRowStart + 1);
|
||||
|
||||
// If extraRowEnd is lower then 7, there was no next row found.
|
||||
if ($extraRowEnd < 7) {
|
||||
break;
|
||||
}
|
||||
|
||||
// If tmpXmlRow doesn't contain continue, this row is no longer part of the spanned row.
|
||||
$tmpXmlRow = $this->getSlice($extraRowStart, $extraRowEnd);
|
||||
if (!preg_match('#<w:vMerge/>#', $tmpXmlRow) &&
|
||||
!preg_match('#<w:vMerge w:val="continue" />#', $tmpXmlRow)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
$tableStart = $this->findTableStart($extraRowEnd + 1);
|
||||
$tableEnd = $this->findTableEnd($extraRowEnd + 1);
|
||||
$xmlTable = $this->getSlice($tableStart, $tableEnd);
|
||||
if (substr_count($xmlTable, '<w:tr') === 1) {
|
||||
$this->tempDocumentMainPart = $this->getSlice(0, $tableStart) . $this->getSlice($tableEnd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->tempDocumentMainPart = $this->getSlice(0, $extraRowStart) . $this->getSlice($extraRowEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones a table row and populates it's values from a two-dimensional array in a template document.
|
||||
*
|
||||
@@ -792,8 +900,12 @@ class TemplateProcessor
|
||||
{
|
||||
$xmlBlock = null;
|
||||
$matches = [];
|
||||
$escapedMacroOpeningChars = self::$macroOpeningChars;
|
||||
$escapedMacroClosingChars = self::$macroClosingChars;
|
||||
preg_match(
|
||||
'/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\${' . $blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\${\/' . $blockname . '}<\/w:.*?p>)/is',
|
||||
//'/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\{{' . $blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\{{\/' . $blockname . '}<\/w:.*?p>)/is',
|
||||
'/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\\' . $escapedMacroOpeningChars . $blockname . $escapedMacroClosingChars . '<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\\' . $escapedMacroOpeningChars . '\/' . $blockname . $escapedMacroClosingChars . '<\/w:.*?p>)/is',
|
||||
//'/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\\'. $escapedMacroOpeningChars . $blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\\'.$escapedMacroOpeningChars.'\/' . $blockname . '}<\/w:.*?p>)/is',
|
||||
$this->tempDocumentMainPart,
|
||||
$matches
|
||||
);
|
||||
@@ -832,8 +944,10 @@ class TemplateProcessor
|
||||
public function replaceBlock($blockname, $replacement): void
|
||||
{
|
||||
$matches = [];
|
||||
$escapedMacroOpeningChars = preg_quote(self::$macroOpeningChars);
|
||||
$escapedMacroClosingChars = preg_quote(self::$macroClosingChars);
|
||||
preg_match(
|
||||
'/(<\?xml.*)(<w:p.*>\${' . $blockname . '}<\/w:.*?p>)(.*)(<w:p.*\${\/' . $blockname . '}<\/w:.*?p>)/is',
|
||||
'/(<\?xml.*)(<w:p.*>' . $escapedMacroOpeningChars . $blockname . $escapedMacroClosingChars . '<\/w:.*?p>)(.*)(<w:p.*' . $escapedMacroOpeningChars . '\/' . $blockname . $escapedMacroClosingChars . '<\/w:.*?p>)/is',
|
||||
$this->tempDocumentMainPart,
|
||||
$matches
|
||||
);
|
||||
@@ -949,8 +1063,12 @@ class TemplateProcessor
|
||||
*/
|
||||
protected function fixBrokenMacros($documentPart)
|
||||
{
|
||||
$brokenMacroOpeningChars = substr(self::$macroOpeningChars, 0, 1);
|
||||
$endMacroOpeningChars = substr(self::$macroOpeningChars, 1);
|
||||
$macroClosingChars = self::$macroClosingChars;
|
||||
|
||||
return preg_replace_callback(
|
||||
'/\$(?:\{|[^{$]*\>\{)[^}$]*\}/U',
|
||||
'/\\' . $brokenMacroOpeningChars . '(?:\\' . $endMacroOpeningChars . '|[^{$]*\>\{)[^' . $macroClosingChars . '$]*\}/U',
|
||||
function ($match) {
|
||||
return strip_tags($match[0]);
|
||||
},
|
||||
@@ -963,7 +1081,7 @@ class TemplateProcessor
|
||||
*
|
||||
* @param mixed $search
|
||||
* @param mixed $replace
|
||||
* @param string $documentPartXML
|
||||
* @param array<int, string>|string $documentPartXML
|
||||
* @param int $limit
|
||||
*
|
||||
* @return string
|
||||
@@ -989,7 +1107,10 @@ class TemplateProcessor
|
||||
protected function getVariablesForPart($documentPartXML)
|
||||
{
|
||||
$matches = [];
|
||||
preg_match_all('/\$\{(.*?)}/i', $documentPartXML, $matches);
|
||||
$escapedMacroOpeningChars = preg_quote(self::$macroOpeningChars);
|
||||
$escapedMacroClosingChars = preg_quote(self::$macroClosingChars);
|
||||
|
||||
preg_match_all("/$escapedMacroOpeningChars(.*?)$escapedMacroClosingChars/i", $documentPartXML, $matches);
|
||||
|
||||
return $matches[1];
|
||||
}
|
||||
@@ -1079,6 +1200,39 @@ class TemplateProcessor
|
||||
return '[Content_Types].xml';
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the start position of the nearest table before $offset.
|
||||
*/
|
||||
private function findTableStart(int $offset): int
|
||||
{
|
||||
$rowStart = strrpos(
|
||||
$this->tempDocumentMainPart,
|
||||
'<w:tbl ',
|
||||
((strlen($this->tempDocumentMainPart) - $offset) * -1)
|
||||
);
|
||||
|
||||
if (!$rowStart) {
|
||||
$rowStart = strrpos(
|
||||
$this->tempDocumentMainPart,
|
||||
'<w:tbl>',
|
||||
((strlen($this->tempDocumentMainPart) - $offset) * -1)
|
||||
);
|
||||
}
|
||||
if (!$rowStart) {
|
||||
throw new Exception('Can not find the start position of the table.');
|
||||
}
|
||||
|
||||
return $rowStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the end position of the nearest table row after $offset.
|
||||
*/
|
||||
private function findTableEnd(int $offset): int
|
||||
{
|
||||
return strpos($this->tempDocumentMainPart, '</w:tbl>', $offset) + 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the start position of the nearest table row before $offset.
|
||||
*
|
||||
@@ -1141,15 +1295,18 @@ class TemplateProcessor
|
||||
protected function indexClonedVariables($count, $xmlBlock)
|
||||
{
|
||||
$results = [];
|
||||
$escapedMacroOpeningChars = preg_quote(self::$macroOpeningChars);
|
||||
$escapedMacroClosingChars = preg_quote(self::$macroClosingChars);
|
||||
|
||||
for ($i = 1; $i <= $count; ++$i) {
|
||||
$results[] = preg_replace('/\$\{([^:]*?)(:.*?)?\}/', '\${\1#' . $i . '\2}', $xmlBlock);
|
||||
$results[] = preg_replace("/$escapedMacroOpeningChars([^:]*?)(:.*?)?$escapedMacroClosingChars/", self::$macroOpeningChars . '\1#' . $i . '\2' . self::$macroClosingChars, $xmlBlock);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Raplaces variables with values from array, array keys are the variable names.
|
||||
* Replaces variables with values from array, array keys are the variable names.
|
||||
*
|
||||
* @param array $variableReplacements
|
||||
* @param string $xmlBlock
|
||||
@@ -1297,7 +1454,7 @@ class TemplateProcessor
|
||||
}
|
||||
|
||||
$unformattedText = preg_replace('/>\s+</', '><', $text);
|
||||
$result = str_replace(['${', '}'], ['</w:t></w:r><w:r>' . $extractedStyle . '<w:t xml:space="preserve">${', '}</w:t></w:r><w:r>' . $extractedStyle . '<w:t xml:space="preserve">'], $unformattedText);
|
||||
$result = str_replace([self::$macroOpeningChars, self::$macroClosingChars], ['</w:t></w:r><w:r>' . $extractedStyle . '<w:t xml:space="preserve">' . self::$macroOpeningChars, self::$macroClosingChars . '</w:t></w:r><w:r>' . $extractedStyle . '<w:t xml:space="preserve">'], $unformattedText);
|
||||
|
||||
return str_replace(['<w:r>' . $extractedStyle . '<w:t xml:space="preserve"></w:t></w:r>', '<w:r><w:t xml:space="preserve"></w:t></w:r>', '<w:t>'], ['', '', '<w:t xml:space="preserve">'], $result);
|
||||
}
|
||||
@@ -1311,6 +1468,25 @@ class TemplateProcessor
|
||||
*/
|
||||
protected function textNeedsSplitting($text)
|
||||
{
|
||||
return preg_match('/[^>]\${|}[^<]/i', $text) == 1;
|
||||
$escapedMacroOpeningChars = preg_quote(self::$macroOpeningChars);
|
||||
$escapedMacroClosingChars = preg_quote(self::$macroClosingChars);
|
||||
|
||||
return 1 === preg_match('/[^>]' . $escapedMacroOpeningChars . '|' . $escapedMacroClosingChars . '[^<]/i', $text);
|
||||
}
|
||||
|
||||
public function setMacroOpeningChars(string $macroOpeningChars): void
|
||||
{
|
||||
self::$macroOpeningChars = $macroOpeningChars;
|
||||
}
|
||||
|
||||
public function setMacroClosingChars(string $macroClosingChars): void
|
||||
{
|
||||
self::$macroClosingChars = $macroClosingChars;
|
||||
}
|
||||
|
||||
public function setMacroChars(string $macroOpeningChars, string $macroClosingChars): void
|
||||
{
|
||||
self::$macroOpeningChars = $macroOpeningChars;
|
||||
self::$macroClosingChars = $macroClosingChars;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,17 +347,8 @@ abstract class AbstractWriter implements WriterInterface
|
||||
|
||||
// Retrive GD image content or get local media
|
||||
if (isset($element['isMemImage']) && $element['isMemImage']) {
|
||||
$image = call_user_func($element['createFunction'], $element['source']);
|
||||
if ($element['imageType'] === 'image/png') {
|
||||
// PNG images need to preserve alpha channel information
|
||||
imagesavealpha($image, true);
|
||||
}
|
||||
ob_start();
|
||||
call_user_func($element['imageFunction'], $image);
|
||||
$imageContents = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$imageContents = $element['imageString'];
|
||||
$zip->addFromString($target, $imageContents);
|
||||
imagedestroy($image);
|
||||
} else {
|
||||
$this->addFileToPackage($zip, $element['source'], $target);
|
||||
}
|
||||
|
||||
120
vendor/phpoffice/phpword/src/PhpWord/Writer/HTML.php
vendored
120
vendor/phpoffice/phpword/src/PhpWord/Writer/HTML.php
vendored
@@ -18,6 +18,9 @@
|
||||
namespace PhpOffice\PhpWord\Writer;
|
||||
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Shared\Validate;
|
||||
use PhpOffice\PhpWord\Style\Font;
|
||||
|
||||
/**
|
||||
* HTML writer.
|
||||
@@ -42,6 +45,27 @@ class HTML extends AbstractWriter implements WriterInterface
|
||||
*/
|
||||
protected $notes = [];
|
||||
|
||||
/**
|
||||
* Callback for editing generated html.
|
||||
*
|
||||
* @var null|callable
|
||||
*/
|
||||
private $editCallback;
|
||||
|
||||
/**
|
||||
* Default generic name for default font for html.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $defaultGenericFont = '';
|
||||
|
||||
/**
|
||||
* Default white space style for html.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $defaultWhiteSpace = '';
|
||||
|
||||
/**
|
||||
* Create new instance.
|
||||
*/
|
||||
@@ -63,10 +87,8 @@ class HTML extends AbstractWriter implements WriterInterface
|
||||
|
||||
/**
|
||||
* Save PhpWord to file.
|
||||
*
|
||||
* @param string $filename
|
||||
*/
|
||||
public function save($filename = null): void
|
||||
public function save(string $filename): void
|
||||
{
|
||||
$this->writeFile($this->openFile($filename), $this->getContent());
|
||||
}
|
||||
@@ -84,14 +106,56 @@ class HTML extends AbstractWriter implements WriterInterface
|
||||
|
||||
$content .= '<!DOCTYPE html>' . PHP_EOL;
|
||||
$content .= '<!-- Generated by PHPWord -->' . PHP_EOL;
|
||||
$content .= '<html>' . PHP_EOL;
|
||||
$langtext = '';
|
||||
$phpWord = $this->getPhpWord();
|
||||
$lang = $phpWord->getSettings()->getThemeFontLang();
|
||||
if (!empty($lang)) {
|
||||
$lang2 = $lang->getLatin();
|
||||
if (!$lang2) {
|
||||
$lang2 = $lang->getEastAsia();
|
||||
}
|
||||
if (!$lang2) {
|
||||
$lang2 = $lang->getBidirectional();
|
||||
}
|
||||
if ($lang2) {
|
||||
$langtext = " lang='" . $lang2 . "'";
|
||||
}
|
||||
}
|
||||
$content .= "<html$langtext>" . PHP_EOL;
|
||||
$content .= $this->getWriterPart('Head')->write();
|
||||
$content .= $this->getWriterPart('Body')->write();
|
||||
$content .= '</html>' . PHP_EOL;
|
||||
|
||||
// Trigger a callback for editing the entire HTML
|
||||
$callback = $this->editCallback;
|
||||
if ($callback !== null) {
|
||||
$content = $callback($content);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the callback to edit the entire HTML.
|
||||
*/
|
||||
public function getEditCallback(): ?callable
|
||||
{
|
||||
return $this->editCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to edit the entire HTML.
|
||||
*
|
||||
* The callback must accept the HTML as string as first parameter,
|
||||
* and it must return the edited HTML as string.
|
||||
*/
|
||||
public function setEditCallback(?callable $callback): self
|
||||
{
|
||||
$this->editCallback = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get is PDF.
|
||||
*
|
||||
@@ -122,4 +186,52 @@ class HTML extends AbstractWriter implements WriterInterface
|
||||
{
|
||||
$this->notes[$noteId] = $noteMark;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get generic name for default font for html.
|
||||
*/
|
||||
public function getDefaultGenericFont(): string
|
||||
{
|
||||
return $this->defaultGenericFont;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set generic name for default font for html.
|
||||
*/
|
||||
public function setDefaultGenericFont(string $value): self
|
||||
{
|
||||
$this->defaultGenericFont = Validate::validateCSSGenericFont($value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default white space style for html.
|
||||
*/
|
||||
public function getDefaultWhiteSpace(): string
|
||||
{
|
||||
return $this->defaultWhiteSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default white space style for html.
|
||||
*/
|
||||
public function setDefaultWhiteSpace(string $value): self
|
||||
{
|
||||
$this->defaultWhiteSpace = Validate::validateCSSWhiteSpace($value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape string or not depending on setting.
|
||||
*/
|
||||
public function escapeHTML(string $txt): string
|
||||
{
|
||||
if (Settings::isOutputEscapingEnabled()) {
|
||||
return htmlspecialchars($txt, ENT_QUOTES | (defined('ENT_SUBSTITUTE') ? ENT_SUBSTITUTE : 0), 'UTF-8');
|
||||
}
|
||||
|
||||
return $txt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Element;
|
||||
|
||||
use Laminas\Escaper\Escaper;
|
||||
use PhpOffice\PhpWord\Element\AbstractElement as Element;
|
||||
use PhpOffice\PhpWord\Writer\AbstractWriter;
|
||||
use PhpOffice\PhpWord\Writer\HTML;
|
||||
|
||||
/**
|
||||
* Abstract HTML element writer.
|
||||
@@ -31,7 +30,7 @@ abstract class AbstractElement
|
||||
/**
|
||||
* Parent writer.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
|
||||
* @var HTML
|
||||
*/
|
||||
protected $parentWriter;
|
||||
|
||||
@@ -49,11 +48,6 @@ abstract class AbstractElement
|
||||
*/
|
||||
protected $withoutP = false;
|
||||
|
||||
/**
|
||||
* @var \Laminas\Escaper\Escaper|\PhpOffice\PhpWord\Escaper\AbstractEscaper
|
||||
*/
|
||||
protected $escaper;
|
||||
|
||||
/**
|
||||
* Write element.
|
||||
*/
|
||||
@@ -64,12 +58,11 @@ abstract class AbstractElement
|
||||
*
|
||||
* @param bool $withoutP
|
||||
*/
|
||||
public function __construct(AbstractWriter $parentWriter, Element $element, $withoutP = false)
|
||||
public function __construct(HTML $parentWriter, Element $element, $withoutP = false)
|
||||
{
|
||||
$this->parentWriter = $parentWriter;
|
||||
$this->element = $element;
|
||||
$this->withoutP = $withoutP;
|
||||
$this->escaper = new Escaper();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Writer\HTML;
|
||||
|
||||
/**
|
||||
* Link element HTML writer.
|
||||
@@ -39,11 +39,11 @@ class Link extends Text
|
||||
|
||||
$prefix = $this->element->isInternal() ? '#' : '';
|
||||
$content = $this->writeOpening();
|
||||
if (Settings::isOutputEscapingEnabled()) {
|
||||
$content .= "<a href=\"{$prefix}{$this->escaper->escapeHtmlAttr($this->element->getSource())}\">{$this->escaper->escapeHtml($this->element->getText())}</a>";
|
||||
} else {
|
||||
$content .= "<a href=\"{$prefix}{$this->element->getSource()}\">{$this->element->getText()}</a>";
|
||||
}
|
||||
$content .= "<a href=\"{$prefix}"
|
||||
. $this->parentWriter->escapeHTML($this->element->getSource())
|
||||
. '">'
|
||||
. $this->parentWriter->escapeHTML($this->element->getText())
|
||||
. '</a>';
|
||||
$content .= $this->writeClosing();
|
||||
|
||||
return $content;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Writer\HTML;
|
||||
|
||||
/**
|
||||
* ListItem element HTML writer.
|
||||
@@ -37,11 +37,7 @@ class ListItem extends AbstractElement
|
||||
return '';
|
||||
}
|
||||
|
||||
if (Settings::isOutputEscapingEnabled()) {
|
||||
$content = '<p>' . $this->escaper->escapeHtml($this->element->getTextObject()->getText()) . '</p>' . PHP_EOL;
|
||||
} else {
|
||||
$content = '<p>' . $this->element->getTextObject()->getText() . '</p>' . PHP_EOL;
|
||||
}
|
||||
$content = '<p>' . $this->parentWriter->escapeHTML($this->element->getTextObject()->getText()) . '</p>' . PHP_EOL;
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Writer\PDF\TCPDF;
|
||||
|
||||
/**
|
||||
* PageBreak element HTML writer.
|
||||
*
|
||||
@@ -35,10 +37,13 @@ class PageBreak extends TextBreak
|
||||
{
|
||||
/** @var \PhpOffice\PhpWord\Writer\HTML $parentWriter Type hint */
|
||||
$parentWriter = $this->parentWriter;
|
||||
if ($parentWriter instanceof TCPDF) {
|
||||
return '<br pagebreak="true"/>';
|
||||
}
|
||||
if ($parentWriter->isPdf()) {
|
||||
return '<pagebreak style="page-break-before: always;" pagebreak="true"></pagebreak>';
|
||||
}
|
||||
|
||||
return '';
|
||||
return '<div style="page-break-before: always; height: 0; margin: 0; padding: 0; overflow: hidden;"> </div>' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Writer\HTML\Style\Table as TableStyleWriter;
|
||||
|
||||
/**
|
||||
* Table element HTML writer.
|
||||
*
|
||||
@@ -39,7 +41,7 @@ class Table extends AbstractElement
|
||||
$rows = $this->element->getRows();
|
||||
$rowCount = count($rows);
|
||||
if ($rowCount > 0) {
|
||||
$content .= '<table' . self::getTableStyle($this->element->getStyle()) . '>' . PHP_EOL;
|
||||
$content .= '<table' . $this->getTableStyle($this->element->getStyle()) . '>' . PHP_EOL;
|
||||
|
||||
for ($i = 0; $i < $rowCount; ++$i) {
|
||||
/** @var \PhpOffice\PhpWord\Element\Row $row Type hint */
|
||||
@@ -51,10 +53,10 @@ class Table extends AbstractElement
|
||||
$rowCellCount = count($rowCells);
|
||||
for ($j = 0; $j < $rowCellCount; ++$j) {
|
||||
$cellStyle = $rowCells[$j]->getStyle();
|
||||
$cellStyleCss = $this->getTableStyle($cellStyle);
|
||||
$cellBgColor = $cellStyle->getBgColor();
|
||||
$cellBgColor === 'auto' && $cellBgColor = null; // auto cannot be parsed to hexadecimal number
|
||||
$cellFgColor = null;
|
||||
if ($cellBgColor) {
|
||||
if ($cellBgColor && $cellBgColor !== 'auto') {
|
||||
$red = hexdec(substr($cellBgColor, 0, 2));
|
||||
$green = hexdec(substr($cellBgColor, 2, 2));
|
||||
$blue = hexdec(substr($cellBgColor, 4, 2));
|
||||
@@ -67,12 +69,8 @@ class Table extends AbstractElement
|
||||
if ($cellVMerge === 'restart') {
|
||||
for ($k = $i + 1; $k < $rowCount; ++$k) {
|
||||
$kRowCells = $rows[$k]->getCells();
|
||||
if (isset($kRowCells[$j])) {
|
||||
if ($kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
|
||||
++$cellRowSpan;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (isset($kRowCells[$j]) && $kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
|
||||
++$cellRowSpan;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -83,22 +81,18 @@ class Table extends AbstractElement
|
||||
$cellTag = $tblHeader ? 'th' : 'td';
|
||||
$cellColSpanAttr = (is_numeric($cellColSpan) && ($cellColSpan > 1) ? " colspan=\"{$cellColSpan}\"" : '');
|
||||
$cellRowSpanAttr = ($cellRowSpan > 1 ? " rowspan=\"{$cellRowSpan}\"" : '');
|
||||
$cellBgColorAttr = (null === $cellBgColor ? '' : " bgcolor=\"#{$cellBgColor}\"");
|
||||
$cellFgColorAttr = (null === $cellFgColor ? '' : " color=\"#{$cellFgColor}\"");
|
||||
$content .= "<{$cellTag}{$cellColSpanAttr}{$cellRowSpanAttr}{$cellBgColorAttr}{$cellFgColorAttr}>" . PHP_EOL;
|
||||
$cellBgColorAttr = (empty($cellBgColor) ? '' : " bgcolor=\"#{$cellBgColor}\"");
|
||||
$cellFgColorAttr = (empty($cellFgColor) ? '' : " color=\"#{$cellFgColor}\"");
|
||||
$content .= "<{$cellTag}{$cellStyleCss}{$cellColSpanAttr}{$cellRowSpanAttr}{$cellBgColorAttr}{$cellFgColorAttr}>" . PHP_EOL;
|
||||
$writer = new Container($this->parentWriter, $rowCells[$j]);
|
||||
$content .= $writer->write();
|
||||
if ($cellRowSpan > 1) {
|
||||
// There shouldn't be any content in the subsequent merged cells, but lets check anyway
|
||||
for ($k = $i + 1; $k < $rowCount; ++$k) {
|
||||
$kRowCells = $rows[$k]->getCells();
|
||||
if (isset($kRowCells[$j])) {
|
||||
if ($kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
|
||||
$writer = new Container($this->parentWriter, $kRowCells[$j]);
|
||||
$content .= $writer->write();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (isset($kRowCells[$j]) && $kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
|
||||
$writer = new Container($this->parentWriter, $kRowCells[$j]);
|
||||
$content .= $writer->write();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -118,26 +112,25 @@ class Table extends AbstractElement
|
||||
/**
|
||||
* Translates Table style in CSS equivalent.
|
||||
*
|
||||
* @param null|\PhpOffice\PhpWord\Style\Table|string $tableStyle
|
||||
*
|
||||
* @return string
|
||||
* @param null|\PhpOffice\PhpWord\Style\Cell|\PhpOffice\PhpWord\Style\Table|string $tableStyle
|
||||
*/
|
||||
private function getTableStyle($tableStyle = null)
|
||||
private function getTableStyle($tableStyle = null): string
|
||||
{
|
||||
if ($tableStyle == null) {
|
||||
return '';
|
||||
}
|
||||
if (is_string($tableStyle)) {
|
||||
$style = ' class="' . $tableStyle;
|
||||
} else {
|
||||
$style = ' style="';
|
||||
if ($tableStyle->getLayout() == \PhpOffice\PhpWord\Style\Table::LAYOUT_FIXED) {
|
||||
$style .= 'table-layout: fixed;';
|
||||
} elseif ($tableStyle->getLayout() == \PhpOffice\PhpWord\Style\Table::LAYOUT_AUTO) {
|
||||
$style .= 'table-layout: auto;';
|
||||
}
|
||||
|
||||
return $style . '"';
|
||||
}
|
||||
|
||||
return $style . '"';
|
||||
$styleWriter = new TableStyleWriter($tableStyle);
|
||||
$style = $styleWriter->write();
|
||||
if ($style === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return ' style="' . $style . '"';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Element\TrackChange;
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Style;
|
||||
use PhpOffice\PhpWord\Style\Font;
|
||||
use PhpOffice\PhpWord\Style\Paragraph;
|
||||
use PhpOffice\PhpWord\Writer\HTML;
|
||||
use PhpOffice\PhpWord\Writer\HTML\Style\Font as FontStyleWriter;
|
||||
use PhpOffice\PhpWord\Writer\HTML\Style\Paragraph as ParagraphStyleWriter;
|
||||
|
||||
@@ -66,19 +67,21 @@ class Text extends AbstractElement
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$this->processFontStyle();
|
||||
|
||||
/** @var \PhpOffice\PhpWord\Element\Text $element Type hint */
|
||||
$element = $this->element;
|
||||
$this->getFontStyle();
|
||||
|
||||
$text = $this->parentWriter->escapeHTML($element->getText());
|
||||
if (!$this->withoutP && !trim($text)) {
|
||||
$text = ' ';
|
||||
}
|
||||
|
||||
$content = '';
|
||||
$content .= $this->writeOpening();
|
||||
$content .= $this->openingText;
|
||||
$content .= $this->openingTags;
|
||||
if (Settings::isOutputEscapingEnabled()) {
|
||||
$content .= $this->escaper->escapeHtml($element->getText());
|
||||
} else {
|
||||
$content .= $element->getText();
|
||||
}
|
||||
$content .= $text;
|
||||
$content .= $this->closingTags;
|
||||
$content .= $this->closingText;
|
||||
$content .= $this->writeClosing();
|
||||
@@ -115,10 +118,7 @@ class Text extends AbstractElement
|
||||
{
|
||||
$content = '';
|
||||
if (!$this->withoutP) {
|
||||
$style = '';
|
||||
if (method_exists($this->element, 'getParagraphStyle')) {
|
||||
$style = $this->getParagraphStyle();
|
||||
}
|
||||
$style = $this->getParagraphStyle();
|
||||
$content .= "<p{$style}>";
|
||||
}
|
||||
|
||||
@@ -141,12 +141,7 @@ class Text extends AbstractElement
|
||||
$content .= $this->writeTrackChangeClosing();
|
||||
|
||||
if (!$this->withoutP) {
|
||||
if (Settings::isOutputEscapingEnabled()) {
|
||||
$content .= $this->escaper->escapeHtml($this->closingText);
|
||||
} else {
|
||||
$content .= $this->closingText;
|
||||
}
|
||||
|
||||
$content .= $this->parentWriter->escapeHTML($this->closingText);
|
||||
$content .= '</p>' . PHP_EOL;
|
||||
}
|
||||
|
||||
@@ -228,6 +223,7 @@ class Text extends AbstractElement
|
||||
$pStyleIsObject = ($paragraphStyle instanceof Paragraph);
|
||||
if ($pStyleIsObject) {
|
||||
$styleWriter = new ParagraphStyleWriter($paragraphStyle);
|
||||
$styleWriter->setParentWriter($this->parentWriter);
|
||||
$style = $styleWriter->write();
|
||||
} elseif (is_string($paragraphStyle)) {
|
||||
$style = $paragraphStyle;
|
||||
@@ -243,22 +239,50 @@ class Text extends AbstractElement
|
||||
/**
|
||||
* Get font style.
|
||||
*/
|
||||
private function getFontStyle(): void
|
||||
private function processFontStyle(): void
|
||||
{
|
||||
/** @var \PhpOffice\PhpWord\Element\Text $element Type hint */
|
||||
$element = $this->element;
|
||||
$style = '';
|
||||
|
||||
$attributeStyle = $attributeLang = '';
|
||||
$lang = null;
|
||||
|
||||
$fontStyle = $element->getFontStyle();
|
||||
$fStyleIsObject = ($fontStyle instanceof Font);
|
||||
if ($fStyleIsObject) {
|
||||
if ($fontStyle instanceof Font) {
|
||||
// Attribute style
|
||||
$styleWriter = new FontStyleWriter($fontStyle);
|
||||
$style = $styleWriter->write();
|
||||
} elseif (is_string($fontStyle)) {
|
||||
$style = $fontStyle;
|
||||
$fontCSS = $styleWriter->write();
|
||||
if ($fontCSS) {
|
||||
$attributeStyle = ' style="' . $fontCSS . '"';
|
||||
}
|
||||
// Attribute Lang
|
||||
$lang = $fontStyle->getLang();
|
||||
} elseif (!empty($fontStyle)) {
|
||||
// Attribute class
|
||||
$attributeStyle = ' class="' . $fontStyle . '"';
|
||||
// Attribute Lang
|
||||
/** @var Font $cssClassStyle */
|
||||
$cssClassStyle = Style::getStyle($fontStyle);
|
||||
if ($cssClassStyle !== null && method_exists($cssClassStyle, 'getLang')) {
|
||||
$lang = $cssClassStyle->getLang();
|
||||
}
|
||||
}
|
||||
if ($style) {
|
||||
$attribute = $fStyleIsObject ? 'style' : 'class';
|
||||
$this->openingTags = "<span {$attribute}=\"{$style}\">";
|
||||
|
||||
if ($lang) {
|
||||
$attributeLang = $lang->getLatin();
|
||||
if (!$attributeLang) {
|
||||
$attributeLang = $lang->getEastAsia();
|
||||
}
|
||||
if (!$attributeLang) {
|
||||
$attributeLang = $lang->getBidirectional();
|
||||
}
|
||||
if ($attributeLang) {
|
||||
$attributeLang = " lang='$attributeLang'";
|
||||
}
|
||||
}
|
||||
|
||||
if ($attributeStyle || $attributeLang) {
|
||||
$this->openingTags = "<span$attributeLang$attributeStyle>";
|
||||
$this->closingTags = '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Writer\HTML;
|
||||
|
||||
/**
|
||||
* TextRun element HTML writer.
|
||||
@@ -41,10 +41,8 @@ class Title extends AbstractElement
|
||||
|
||||
$text = $this->element->getText();
|
||||
if (is_string($text)) {
|
||||
if (Settings::isOutputEscapingEnabled()) {
|
||||
$text = $this->escaper->escapeHtml($text);
|
||||
}
|
||||
} elseif ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) {
|
||||
$text = $this->parentWriter->escapeHTML($text);
|
||||
} else {
|
||||
$writer = new Container($this->parentWriter, $text);
|
||||
$text = $writer->write();
|
||||
}
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Part;
|
||||
|
||||
use Laminas\Escaper\Escaper;
|
||||
use PhpOffice\PhpWord\Exception\Exception;
|
||||
use PhpOffice\PhpWord\Writer\AbstractWriter;
|
||||
use PhpOffice\PhpWord\Writer\HTML;
|
||||
|
||||
/**
|
||||
* @since 0.11.0
|
||||
@@ -27,35 +26,22 @@ use PhpOffice\PhpWord\Writer\AbstractWriter;
|
||||
abstract class AbstractPart
|
||||
{
|
||||
/**
|
||||
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
|
||||
* @var ?HTML
|
||||
*/
|
||||
private $parentWriter;
|
||||
|
||||
/**
|
||||
* @var \Laminas\Escaper\Escaper
|
||||
*/
|
||||
protected $escaper;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->escaper = new Escaper();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function write();
|
||||
|
||||
/**
|
||||
* @param \PhpOffice\PhpWord\Writer\AbstractWriter $writer
|
||||
*/
|
||||
public function setParentWriter(?AbstractWriter $writer = null): void
|
||||
public function setParentWriter(?HTML $writer = null): void
|
||||
{
|
||||
$this->parentWriter = $writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PhpOffice\PhpWord\Writer\AbstractWriter
|
||||
* @return HTML
|
||||
*/
|
||||
public function getParentWriter()
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace PhpOffice\PhpWord\Writer\HTML\Part;
|
||||
|
||||
use PhpOffice\PhpWord\Writer\HTML\Element\Container;
|
||||
use PhpOffice\PhpWord\Writer\HTML\Element\TextRun as TextRunWriter;
|
||||
use PhpOffice\PhpWord\Writer\PDF\TCPDF;
|
||||
|
||||
/**
|
||||
* RTF body part writer.
|
||||
@@ -40,9 +41,18 @@ class Body extends AbstractPart
|
||||
|
||||
$content .= '<body>' . PHP_EOL;
|
||||
$sections = $phpWord->getSections();
|
||||
$secno = 0;
|
||||
$isTCPDFWriter = $this->getParentWriter() instanceof TCPDF;
|
||||
foreach ($sections as $section) {
|
||||
++$secno;
|
||||
if ($isTCPDFWriter && $secno > 1) {
|
||||
$content .= "<div style=\"page: page$secno; page-break-before:always;\">" . PHP_EOL;
|
||||
} else {
|
||||
$content .= "<div style='page: page$secno'>" . PHP_EOL;
|
||||
}
|
||||
$writer = new Container($this->getParentWriter(), $section);
|
||||
$content .= $writer->write();
|
||||
$content .= '</div>' . PHP_EOL;
|
||||
}
|
||||
|
||||
$content .= $this->writeNotes();
|
||||
|
||||
@@ -18,12 +18,15 @@
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Part;
|
||||
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Shared\Converter;
|
||||
use PhpOffice\PhpWord\Style;
|
||||
use PhpOffice\PhpWord\Style\Font;
|
||||
use PhpOffice\PhpWord\Style\Paragraph;
|
||||
use PhpOffice\PhpWord\Style\Table;
|
||||
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;
|
||||
use PhpOffice\PhpWord\Writer\HTML\Style\Table as TableStyleWriter;
|
||||
|
||||
/**
|
||||
* RTF head part writer.
|
||||
@@ -63,8 +66,10 @@ class Head extends AbstractPart
|
||||
$method = 'get' . $key;
|
||||
if ($docProps->$method() != '') {
|
||||
$content .= '<meta name="' . $value . '"'
|
||||
. ' content="' . (Settings::isOutputEscapingEnabled() ? $this->escaper->escapeHtmlAttr($docProps->$method()) : $docProps->$method()) . '"'
|
||||
. ' />' . PHP_EOL;
|
||||
. ' content="'
|
||||
. $this->getParentWriter()->escapeHTML($docProps->$method())
|
||||
. '"'
|
||||
. ' />' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
$content .= $this->writeStyles();
|
||||
@@ -75,19 +80,27 @@ class Head extends AbstractPart
|
||||
|
||||
/**
|
||||
* Get styles.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function writeStyles()
|
||||
private function writeStyles(): string
|
||||
{
|
||||
$css = '<style>' . PHP_EOL;
|
||||
|
||||
// Default styles
|
||||
$defaultStyles = [
|
||||
'*' => [
|
||||
'font-family' => Settings::getDefaultFontName(),
|
||||
'font-size' => Settings::getDefaultFontSize() . 'pt',
|
||||
],
|
||||
$astarray = [
|
||||
'font-family' => $this->getFontFamily(Settings::getDefaultFontName(), $this->getParentWriter()->getDefaultGenericFont()),
|
||||
'font-size' => Settings::getDefaultFontSize() . 'pt',
|
||||
];
|
||||
// Mpdf sometimes needs separate tag for body; doesn't harm others.
|
||||
$bodyarray = $astarray;
|
||||
|
||||
$defaultWhiteSpace = $this->getParentWriter()->getDefaultWhiteSpace();
|
||||
if ($defaultWhiteSpace) {
|
||||
$astarray['white-space'] = $defaultWhiteSpace;
|
||||
}
|
||||
|
||||
foreach ([
|
||||
'body' => $bodyarray,
|
||||
'*' => $astarray,
|
||||
'a.NoteRef' => [
|
||||
'text-decoration' => 'none',
|
||||
],
|
||||
@@ -106,8 +119,7 @@ class Head extends AbstractPart
|
||||
'td' => [
|
||||
'border' => '1px solid black',
|
||||
],
|
||||
];
|
||||
foreach ($defaultStyles as $selector => $style) {
|
||||
] as $selector => $style) {
|
||||
$styleWriter = new GenericStyleWriter($style);
|
||||
$css .= $selector . ' {' . $styleWriter->write() . '}' . PHP_EOL;
|
||||
}
|
||||
@@ -116,23 +128,81 @@ class Head extends AbstractPart
|
||||
$customStyles = Style::getStyles();
|
||||
if (is_array($customStyles)) {
|
||||
foreach ($customStyles as $name => $style) {
|
||||
$styleParagraph = null;
|
||||
if ($style instanceof Font) {
|
||||
$styleWriter = new FontStyleWriter($style);
|
||||
if ($style->getStyleType() == 'title') {
|
||||
$name = str_replace('Heading_', 'h', $name);
|
||||
$styleParagraph = $style->getParagraph();
|
||||
$style = $styleParagraph;
|
||||
} else {
|
||||
$name = '.' . $name;
|
||||
}
|
||||
$css .= "{$name} {" . $styleWriter->write() . '}' . PHP_EOL;
|
||||
} elseif ($style instanceof Paragraph) {
|
||||
}
|
||||
if ($style instanceof Paragraph) {
|
||||
$styleWriter = new ParagraphStyleWriter($style);
|
||||
$name = '.' . $name;
|
||||
$styleWriter->setParentWriter($this->getParentWriter());
|
||||
if (!$styleParagraph) {
|
||||
$name = '.' . $name;
|
||||
}
|
||||
if ($name === '.Normal') {
|
||||
$name = "p, $name";
|
||||
}
|
||||
$css .= "{$name} {" . $styleWriter->write() . '}' . PHP_EOL;
|
||||
}
|
||||
if ($style instanceof Table) {
|
||||
$styleWriter = new TableStyleWriter($style);
|
||||
$css .= ".{$name} {" . $styleWriter->write() . '}' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$css .= 'body > div + div {page-break-before: always;}' . PHP_EOL;
|
||||
$css .= 'div > *:first-child {page-break-before: auto;}' . PHP_EOL;
|
||||
|
||||
$sectionNum = 0;
|
||||
foreach ($this->getParentWriter()->getPhpWord()->getSections() as $section) {
|
||||
++$sectionNum;
|
||||
|
||||
$css .= "@page page$sectionNum {";
|
||||
|
||||
$paperSize = $section->getStyle()->getPaperSize();
|
||||
$orientation = $section->getStyle()->getOrientation();
|
||||
if ($this->getParentWriter()->isPdf()) {
|
||||
if ($orientation === 'landscape') {
|
||||
$paperSize .= '-L';
|
||||
}
|
||||
$css .= "sheet-size: $paperSize; ";
|
||||
} else {
|
||||
$css .= "size: $paperSize $orientation; ";
|
||||
}
|
||||
|
||||
$css .= 'margin-right: ' . (string) ($section->getStyle()->getMarginRight() / Converter::INCH_TO_TWIP) . 'in; ';
|
||||
$css .= 'margin-left: ' . (string) ($section->getStyle()->getMarginLeft() / Converter::INCH_TO_TWIP) . 'in; ';
|
||||
$css .= 'margin-top: ' . (string) ($section->getStyle()->getMarginTop() / Converter::INCH_TO_TWIP) . 'in; ';
|
||||
$css .= 'margin-bottom: ' . (string) ($section->getStyle()->getMarginBottom() / Converter::INCH_TO_TWIP) . 'in; ';
|
||||
$css .= '}' . PHP_EOL;
|
||||
}
|
||||
|
||||
$css .= '</style>' . PHP_EOL;
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set font and alternates for css font-family.
|
||||
*/
|
||||
private function getFontFamily(string $font, string $genericFont): string
|
||||
{
|
||||
if (empty($font)) {
|
||||
return '';
|
||||
}
|
||||
$fontfamily = "'" . htmlspecialchars($font, ENT_QUOTES, 'UTF-8') . "'";
|
||||
if (!empty($genericFont)) {
|
||||
$fontfamily .= ", $genericFont";
|
||||
}
|
||||
|
||||
return $fontfamily;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Style;
|
||||
|
||||
use PhpOffice\PhpWord\Style\AbstractStyle as Style;
|
||||
use PhpOffice\PhpWord\Style\AbstractStyle as StyleAbstract;
|
||||
use PhpOffice\PhpWord\Writer\HTML;
|
||||
|
||||
/**
|
||||
* Style writer.
|
||||
@@ -29,26 +30,28 @@ abstract class AbstractStyle
|
||||
/**
|
||||
* Parent writer.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
|
||||
* @var HTML
|
||||
*/
|
||||
private $parentWriter;
|
||||
|
||||
/**
|
||||
* Style.
|
||||
*
|
||||
* @var array|\PhpOffice\PhpWord\Style\AbstractStyle
|
||||
* @var null|array|StyleAbstract
|
||||
*/
|
||||
private $style;
|
||||
|
||||
/**
|
||||
* Write style.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function write();
|
||||
|
||||
/**
|
||||
* Create new instance.
|
||||
*
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $style
|
||||
* @param array|StyleAbstract $style
|
||||
*/
|
||||
public function __construct($style = null)
|
||||
{
|
||||
@@ -58,7 +61,7 @@ abstract class AbstractStyle
|
||||
/**
|
||||
* Set parent writer.
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Writer\AbstractWriter $writer
|
||||
* @param HTML $writer
|
||||
*/
|
||||
public function setParentWriter($writer): void
|
||||
{
|
||||
@@ -68,7 +71,7 @@ abstract class AbstractStyle
|
||||
/**
|
||||
* Get parent writer.
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Writer\AbstractWriter
|
||||
* @return HTML
|
||||
*/
|
||||
public function getParentWriter()
|
||||
{
|
||||
@@ -78,11 +81,11 @@ abstract class AbstractStyle
|
||||
/**
|
||||
* Get style.
|
||||
*
|
||||
* @return array|\PhpOffice\PhpWord\Style\AbstractStyle $style
|
||||
* @return null|array|string|StyleAbstract
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
if (!$this->style instanceof Style && !is_array($this->style)) {
|
||||
if (!$this->style instanceof StyleAbstract && !is_array($this->style)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
@@ -39,14 +39,14 @@ class Font extends AbstractStyle
|
||||
}
|
||||
$css = [];
|
||||
|
||||
$font = $style->getName();
|
||||
$font = $this->getFontFamily($style->getName(), $style->getFallbackFont());
|
||||
$size = $style->getSize();
|
||||
$color = $style->getColor();
|
||||
$fgColor = $style->getFgColor();
|
||||
$underline = $style->getUnderline() != FontStyle::UNDERLINE_NONE;
|
||||
$lineThrough = $style->isStrikethrough() || $style->isDoubleStrikethrough();
|
||||
|
||||
$css['font-family'] = $this->getValueIf($font !== null, "'{$font}'");
|
||||
$css['font-family'] = $this->getValueIf(!empty($font), $font);
|
||||
$css['font-size'] = $this->getValueIf($size !== null, "{$size}pt");
|
||||
$css['color'] = $this->getValueIf($color !== null, "#{$color}");
|
||||
$css['background'] = $this->getValueIf($fgColor != '', $fgColor);
|
||||
@@ -61,10 +61,35 @@ class Font extends AbstractStyle
|
||||
$css['text-transform'] = $this->getValueIf($style->isAllCaps(), 'uppercase');
|
||||
$css['font-variant'] = $this->getValueIf($style->isSmallCaps(), 'small-caps');
|
||||
$css['display'] = $this->getValueIf($style->isHidden(), 'none');
|
||||
$whitespace = $style->getWhiteSpace();
|
||||
if ($whitespace) {
|
||||
$css['white-space'] = $whitespace;
|
||||
}
|
||||
|
||||
$spacing = $style->getSpacing();
|
||||
$css['letter-spacing'] = $this->getValueIf(null !== $spacing, ($spacing / 20) . 'pt');
|
||||
if ($style->isRTL()) {
|
||||
$css['direction'] = 'rtl';
|
||||
} elseif ($style->isRTL() === false) {
|
||||
$css['direction'] = 'ltr';
|
||||
}
|
||||
|
||||
return $this->assembleCss($css);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set font and alternates for css font-family.
|
||||
*/
|
||||
private function getFontFamily(?string $font, string $genericFont): string
|
||||
{
|
||||
if (empty($font)) {
|
||||
return '';
|
||||
}
|
||||
$fontfamily = "'" . htmlspecialchars($font, ENT_QUOTES, 'UTF-8') . "'";
|
||||
if (!empty($genericFont)) {
|
||||
$fontfamily .= ", $genericFont";
|
||||
}
|
||||
|
||||
return $fontfamily;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Style;
|
||||
|
||||
use PhpOffice\PhpWord\Shared\Converter;
|
||||
use PhpOffice\PhpWord\SimpleType\Jc;
|
||||
use PhpOffice\PhpWord\Writer\PDF\TCPDF;
|
||||
|
||||
/**
|
||||
* Paragraph style HTML writer.
|
||||
@@ -49,6 +51,9 @@ class Paragraph extends AbstractStyle
|
||||
|
||||
break;
|
||||
case Jc::END:
|
||||
$textAlign = $style->isBidi() ? 'left' : 'right';
|
||||
|
||||
break;
|
||||
case Jc::MEDIUM_KASHIDA:
|
||||
case Jc::HIGH_KASHIDA:
|
||||
case Jc::LOW_KASHIDA:
|
||||
@@ -63,9 +68,13 @@ class Paragraph extends AbstractStyle
|
||||
$textAlign = 'justify';
|
||||
|
||||
break;
|
||||
default: //all others, align left
|
||||
case Jc::LEFT:
|
||||
$textAlign = 'left';
|
||||
|
||||
break;
|
||||
default: //all others, including Jc::START
|
||||
$textAlign = $style->isBidi() ? 'right' : 'left';
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -79,9 +88,32 @@ class Paragraph extends AbstractStyle
|
||||
$after = $spacing->getAfter();
|
||||
$css['margin-top'] = $this->getValueIf(null !== $before, ($before / 20) . 'pt');
|
||||
$css['margin-bottom'] = $this->getValueIf(null !== $after, ($after / 20) . 'pt');
|
||||
} else {
|
||||
$css['margin-top'] = '0';
|
||||
$css['margin-bottom'] = '0';
|
||||
}
|
||||
|
||||
// Line Height
|
||||
$lineHeight = $style->getLineHeight();
|
||||
if (!empty($lineHeight)) {
|
||||
$css['line-height'] = $lineHeight;
|
||||
}
|
||||
|
||||
// Indentation (Margin)
|
||||
$indentation = $style->getIndentation();
|
||||
if ($indentation) {
|
||||
$inches = $indentation->getLeft() * 1.0 / Converter::INCH_TO_TWIP;
|
||||
$css[$this->getParentWriter() instanceof TCPDF ? 'text-indent' : 'margin-left'] = ((string) $inches) . 'in';
|
||||
|
||||
$inches = $indentation->getRight() * 1.0 / Converter::INCH_TO_TWIP;
|
||||
$css['margin-right'] = ((string) $inches) . 'in';
|
||||
}
|
||||
|
||||
// Page Break Before
|
||||
if ($style->hasPageBreakBefore()) {
|
||||
$css['page-break-before'] = 'always';
|
||||
}
|
||||
|
||||
// Bidirectional
|
||||
if ($style->isBidi()) {
|
||||
$css['direction'] = 'rtl';
|
||||
}
|
||||
|
||||
return $this->assembleCss($css);
|
||||
|
||||
82
vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Table.php
vendored
Normal file
82
vendor/phpoffice/phpword/src/PhpWord/Writer/HTML/Style/Table.php
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
*
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\HTML\Style;
|
||||
|
||||
use PhpOffice\PhpWord\Style\Cell as StyleCell;
|
||||
use PhpOffice\PhpWord\Style\Table as StyleTable;
|
||||
|
||||
class Table extends AbstractStyle
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$style = $this->getStyle();
|
||||
if (!$style instanceof StyleTable && !$style instanceof StyleCell) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$css = [];
|
||||
if (is_object($style) && method_exists($style, 'getLayout')) {
|
||||
if ($style->getLayout() == StyleTable::LAYOUT_FIXED) {
|
||||
$css['table-layout'] = 'fixed';
|
||||
} elseif ($style->getLayout() == StyleTable::LAYOUT_AUTO) {
|
||||
$css['table-layout'] = 'auto';
|
||||
}
|
||||
}
|
||||
if (is_object($style) && method_exists($style, 'isBidiVisual')) {
|
||||
if ($style->isBidiVisual()) {
|
||||
$css['direction'] = 'rtl';
|
||||
}
|
||||
}
|
||||
|
||||
foreach (['Top', 'Left', 'Bottom', 'Right'] as $direction) {
|
||||
$method = 'getBorder' . $direction . 'Style';
|
||||
if (method_exists($style, $method)) {
|
||||
$outval = $style->{$method}();
|
||||
if ($outval === 'single') {
|
||||
$outval = 'solid';
|
||||
}
|
||||
if (is_string($outval) && 1 == preg_match('/^[a-z]+$/', $outval)) {
|
||||
$css['border-' . lcfirst($direction) . '-style'] = $outval;
|
||||
}
|
||||
}
|
||||
|
||||
$method = 'getBorder' . $direction . 'Color';
|
||||
if (method_exists($style, $method)) {
|
||||
$outval = $style->{$method}();
|
||||
if (is_string($outval) && 1 == preg_match('/^[a-z]+$/', $outval)) {
|
||||
$css['border-' . lcfirst($direction) . '-color'] = $outval;
|
||||
}
|
||||
}
|
||||
|
||||
$method = 'getBorder' . $direction . 'Size';
|
||||
if (method_exists($style, $method)) {
|
||||
$outval = $style->{$method}();
|
||||
if (is_numeric($outval)) {
|
||||
// size is in twips - divide by 20 to get points
|
||||
$css['border-' . lcfirst($direction) . '-width'] = ((string) ($outval / 20)) . 'pt';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->assembleCss($css);
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,12 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer;
|
||||
|
||||
use PhpOffice\Math\Writer\MathML;
|
||||
use PhpOffice\PhpWord\Element\AbstractElement;
|
||||
use PhpOffice\PhpWord\Element\Formula;
|
||||
use PhpOffice\PhpWord\Media;
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\Writer\ODText\Part\AbstractPart;
|
||||
|
||||
/**
|
||||
* ODText writer.
|
||||
@@ -27,10 +31,13 @@ use PhpOffice\PhpWord\PhpWord;
|
||||
*/
|
||||
class ODText extends AbstractWriter implements WriterInterface
|
||||
{
|
||||
/**
|
||||
* @var AbstractElement[]
|
||||
*/
|
||||
protected $objects = [];
|
||||
|
||||
/**
|
||||
* Create new ODText writer.
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\PhpWord $phpWord
|
||||
*/
|
||||
public function __construct(?PhpWord $phpWord = null)
|
||||
{
|
||||
@@ -61,10 +68,8 @@ class ODText extends AbstractWriter implements WriterInterface
|
||||
|
||||
/**
|
||||
* Save PhpWord to file.
|
||||
*
|
||||
* @param string $filename
|
||||
*/
|
||||
public function save($filename = null): void
|
||||
public function save(string $filename): void
|
||||
{
|
||||
$filename = $this->getTempFile($filename);
|
||||
$zip = $this->getZipArchive($filename);
|
||||
@@ -77,8 +82,28 @@ class ODText extends AbstractWriter implements WriterInterface
|
||||
|
||||
// Write parts
|
||||
foreach ($this->parts as $partName => $fileName) {
|
||||
if ($fileName != '') {
|
||||
$zip->addFromString($fileName, $this->getWriterPart($partName)->write());
|
||||
if ($fileName === '') {
|
||||
continue;
|
||||
}
|
||||
$part = $this->getWriterPart($partName);
|
||||
if (!$part instanceof AbstractPart) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$part->setObjects($this->objects);
|
||||
|
||||
$zip->addFromString($fileName, $part->write());
|
||||
|
||||
$this->objects = $part->getObjects();
|
||||
}
|
||||
|
||||
// Write objects charts
|
||||
if (!empty($this->objects)) {
|
||||
$writer = new MathML();
|
||||
foreach ($this->objects as $idxObject => $object) {
|
||||
if ($object instanceof Formula) {
|
||||
$zip->addFromString('Formula' . $idxObject . '/content.xml', $writer->write($object->getMath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
// Not fully implemented
|
||||
// - supports only PAGE and NUMPAGES
|
||||
// - supports only PAGE, NUMPAGES, DATE and FILENAME
|
||||
// - supports only default formats and options
|
||||
// - supports style only if specified by name
|
||||
// - spaces before and after field may be dropped
|
||||
@@ -44,6 +44,7 @@ class Field extends Text
|
||||
case 'date':
|
||||
case 'page':
|
||||
case 'numpages':
|
||||
case 'filename':
|
||||
$this->writeDefault($element, $type);
|
||||
|
||||
break;
|
||||
@@ -78,6 +79,18 @@ class Field extends Text
|
||||
$xmlWriter->startElement('text:page-count');
|
||||
$xmlWriter->endElement();
|
||||
|
||||
break;
|
||||
case 'filename':
|
||||
$xmlWriter->startElement('text:file-name');
|
||||
$xmlWriter->writeAttribute('text:fixed', 'false');
|
||||
$options = $element->getOptions();
|
||||
if ($options != null && in_array('Path', $options)) {
|
||||
$xmlWriter->writeAttribute('text:display', 'full');
|
||||
} else {
|
||||
$xmlWriter->writeAttribute('text:display', 'name');
|
||||
}
|
||||
$xmlWriter->endElement();
|
||||
|
||||
break;
|
||||
}
|
||||
$xmlWriter->endElement(); // text:span
|
||||
|
||||
74
vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Formula.php
vendored
Normal file
74
vendor/phpoffice/phpword/src/PhpWord/Writer/ODText/Element/Formula.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
*
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\ODText\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Element\Formula as ElementFormula;
|
||||
use PhpOffice\PhpWord\Shared\Converter;
|
||||
use PhpOffice\PhpWord\Writer\ODText\Part\AbstractPart;
|
||||
|
||||
/**
|
||||
* Formula element writer.
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
class Formula extends AbstractElement
|
||||
{
|
||||
/**
|
||||
* Write element.
|
||||
*/
|
||||
public function write(): void
|
||||
{
|
||||
$xmlWriter = $this->getXmlWriter();
|
||||
$element = $this->getElement();
|
||||
if (!$element instanceof ElementFormula) {
|
||||
return;
|
||||
}
|
||||
|
||||
$part = $this->getPart();
|
||||
if (!$part instanceof AbstractPart) {
|
||||
return;
|
||||
}
|
||||
|
||||
$objectIdx = $part->addObject($element);
|
||||
|
||||
//$style = $element->getStyle();
|
||||
//$width = Converter::pixelToCm($style->getWidth());
|
||||
//$height = Converter::pixelToCm($style->getHeight());
|
||||
|
||||
$xmlWriter->startElement('text:p');
|
||||
$xmlWriter->writeAttribute('text:style-name', 'OB' . $objectIdx);
|
||||
|
||||
$xmlWriter->startElement('draw:frame');
|
||||
$xmlWriter->writeAttribute('draw:name', $element->getElementId());
|
||||
$xmlWriter->writeAttribute('text:anchor-type', 'as-char');
|
||||
//$xmlWriter->writeAttribute('svg:width', $width . 'cm');
|
||||
//$xmlWriter->writeAttribute('svg:height', $height . 'cm');
|
||||
//$xmlWriter->writeAttribute('draw:z-index', $mediaIndex);
|
||||
|
||||
$xmlWriter->startElement('draw:object');
|
||||
$xmlWriter->writeAttribute('xlink:href', 'Formula' . $objectIdx);
|
||||
$xmlWriter->writeAttribute('xlink:type', 'simple');
|
||||
$xmlWriter->writeAttribute('xlink:show', 'embed');
|
||||
$xmlWriter->writeAttribute('xlink:actuate', 'onLoad');
|
||||
$xmlWriter->endElement(); // draw:object
|
||||
|
||||
$xmlWriter->endElement(); // draw:frame
|
||||
|
||||
$xmlWriter->endElement(); // text:p
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ class Table extends AbstractElement
|
||||
if ($rowCount > 0) {
|
||||
$xmlWriter->startElement('table:table');
|
||||
$xmlWriter->writeAttribute('table:name', $element->getElementId());
|
||||
$xmlWriter->writeAttribute('table:style', $element->getElementId());
|
||||
$xmlWriter->writeAttribute('table:style-name', $element->getElementId());
|
||||
|
||||
// Write columns
|
||||
$this->writeColumns($xmlWriter, $element);
|
||||
|
||||
@@ -55,7 +55,8 @@ class Title extends AbstractElement
|
||||
$text = $element->getText();
|
||||
if (is_string($text)) {
|
||||
$this->writeText($text);
|
||||
} elseif ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) {
|
||||
}
|
||||
if ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) {
|
||||
$containerWriter = new Container($xmlWriter, $text);
|
||||
$containerWriter->write();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\ODText\Part;
|
||||
|
||||
use PhpOffice\PhpWord\Element\AbstractElement;
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Shared\XMLWriter;
|
||||
use PhpOffice\PhpWord\Style;
|
||||
@@ -28,6 +29,11 @@ use PhpOffice\PhpWord\Writer\Word2007\Part\AbstractPart as Word2007AbstractPart;
|
||||
*/
|
||||
abstract class AbstractPart extends Word2007AbstractPart
|
||||
{
|
||||
/**
|
||||
* @var AbstractElement[]
|
||||
*/
|
||||
protected $objects = [];
|
||||
|
||||
/**
|
||||
* @var string Date format
|
||||
*/
|
||||
@@ -102,4 +108,29 @@ abstract class AbstractPart extends Word2007AbstractPart
|
||||
}
|
||||
$xmlWriter->endElement();
|
||||
}
|
||||
|
||||
public function addObject(AbstractElement $object): int
|
||||
{
|
||||
$this->objects[] = $object;
|
||||
|
||||
return count($this->objects) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractElement[] $objects
|
||||
*/
|
||||
public function setObjects(array $objects): self
|
||||
{
|
||||
$this->objects = $objects;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AbstractElement[]
|
||||
*/
|
||||
public function getObjects(): array
|
||||
{
|
||||
return $this->objects;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,8 +135,11 @@ class Content extends AbstractPart
|
||||
$xmlWriter->startElement('text:p');
|
||||
$xmlWriter->writeAttribute('text:style-name', 'SB' . $section->getSectionId());
|
||||
$xmlWriter->endElement();
|
||||
|
||||
$containerWriter = new Container($xmlWriter, $section);
|
||||
$containerWriter->setPart($this);
|
||||
$containerWriter->write();
|
||||
|
||||
$xmlWriter->endElement(); // text:section
|
||||
}
|
||||
|
||||
@@ -198,7 +201,7 @@ class Content extends AbstractPart
|
||||
}
|
||||
|
||||
foreach ($styles as $style) {
|
||||
$sty = $style->getStyleName();
|
||||
$sty = (string) $style->getStyleName();
|
||||
if (substr($sty, 0, 8) === 'Heading_') {
|
||||
$style = new Paragraph();
|
||||
$style->setStyleName('HD' . substr($sty, 8));
|
||||
@@ -280,7 +283,6 @@ class Content extends AbstractPart
|
||||
$sty->setAlignment($style->getAlignment());
|
||||
$this->imageParagraphStyles[] = $sty;
|
||||
} elseif ($element instanceof Table) {
|
||||
/** @var \PhpOffice\PhpWord\Style\Table $style */
|
||||
$style = $element->getStyle();
|
||||
if (is_string($style)) {
|
||||
$style = Style::getStyle($style);
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\ODText\Part;
|
||||
|
||||
use PhpOffice\PhpWord\Element\Formula;
|
||||
use PhpOffice\PhpWord\Media;
|
||||
use PhpOffice\PhpWord\Writer\ODText;
|
||||
|
||||
/**
|
||||
* ODText manifest part writer: META-INF/manifest.xml.
|
||||
@@ -31,7 +33,6 @@ class Manifest extends AbstractPart
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$parts = ['content.xml', 'meta.xml', 'styles.xml'];
|
||||
$xmlWriter = $this->getXmlWriter();
|
||||
|
||||
$xmlWriter->startDocument('1.0', 'UTF-8');
|
||||
@@ -46,7 +47,7 @@ class Manifest extends AbstractPart
|
||||
$xmlWriter->endElement();
|
||||
|
||||
// Parts
|
||||
foreach ($parts as $part) {
|
||||
foreach (['content.xml', 'meta.xml', 'styles.xml'] as $part) {
|
||||
$xmlWriter->startElement('manifest:file-entry');
|
||||
$xmlWriter->writeAttribute('manifest:media-type', 'text/xml');
|
||||
$xmlWriter->writeAttribute('manifest:full-path', $part);
|
||||
@@ -64,6 +65,20 @@ class Manifest extends AbstractPart
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->getObjects() as $idxObject => $object) {
|
||||
if ($object instanceof Formula) {
|
||||
$xmlWriter->startElement('manifest:file-entry');
|
||||
$xmlWriter->writeAttribute('manifest:full-path', 'Formula' . $idxObject . '/content.xml');
|
||||
$xmlWriter->writeAttribute('manifest:media-type', 'text/xml');
|
||||
$xmlWriter->endElement();
|
||||
$xmlWriter->startElement('manifest:file-entry');
|
||||
$xmlWriter->writeAttribute('manifest:full-path', 'Formula' . $idxObject . '/');
|
||||
$xmlWriter->writeAttribute('manifest:version', '1.2');
|
||||
$xmlWriter->writeAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.formula');
|
||||
$xmlWriter->endElement();
|
||||
}
|
||||
}
|
||||
|
||||
$xmlWriter->endElement(); // manifest:manifest
|
||||
|
||||
return $xmlWriter->getData();
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\ODText\Style;
|
||||
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Shared\Converter;
|
||||
use PhpOffice\PhpWord\SimpleType\Jc;
|
||||
use PhpOffice\PhpWord\Style;
|
||||
|
||||
/**
|
||||
* Font style writer.
|
||||
@@ -26,6 +29,16 @@ use PhpOffice\PhpWord\Shared\Converter;
|
||||
*/
|
||||
class Paragraph extends AbstractStyle
|
||||
{
|
||||
private const BIDI_MAP = [
|
||||
Jc::END => Jc::LEFT,
|
||||
Jc::START => Jc::RIGHT,
|
||||
];
|
||||
|
||||
private const NON_BIDI_MAP = [
|
||||
Jc::START => Jc::LEFT,
|
||||
Jc::END => Jc::RIGHT,
|
||||
];
|
||||
|
||||
/**
|
||||
* Write style.
|
||||
*/
|
||||
@@ -42,7 +55,7 @@ class Paragraph extends AbstractStyle
|
||||
|
||||
$xmlWriter->startElement('style:style');
|
||||
|
||||
$styleName = $style->getStyleName();
|
||||
$styleName = (string) $style->getStyleName();
|
||||
$styleAuto = false;
|
||||
$mpm = '';
|
||||
$psm = '';
|
||||
@@ -111,8 +124,18 @@ class Paragraph extends AbstractStyle
|
||||
$xmlWriter->writeAttributeIf($marginTop !== null, 'fo:margin-top', ($marginTop / $twipToPoint) . 'pt');
|
||||
$xmlWriter->writeAttributeIf($marginBottom !== null, 'fo:margin-bottom', ($marginBottom / $twipToPoint) . 'pt');
|
||||
}
|
||||
$temp = $style->getAlignment();
|
||||
$xmlWriter->writeAttributeIf($temp !== '', 'fo:text-align', $temp);
|
||||
$alignment = $style->getAlignment();
|
||||
$bidi = $style->isBidi();
|
||||
$defaultRtl = Settings::isDefaultRtl();
|
||||
if ($alignment === '' && $bidi !== null) {
|
||||
$alignment = Jc::START;
|
||||
}
|
||||
if ($bidi) {
|
||||
$alignment = self::BIDI_MAP[$alignment] ?? $alignment;
|
||||
} elseif ($defaultRtl !== null) {
|
||||
$alignment = self::NON_BIDI_MAP[$alignment] ?? $alignment;
|
||||
}
|
||||
$xmlWriter->writeAttributeIf($alignment !== '', 'fo:text-align', $alignment);
|
||||
$temp = $style->getLineHeight();
|
||||
$xmlWriter->writeAttributeIf($temp !== null, 'fo:line-height', ((string) ($temp * 100) . '%'));
|
||||
$xmlWriter->writeAttributeIf($style->hasPageBreakBefore() === true, 'fo:break-before', 'page');
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace PhpOffice\PhpWord\Writer;
|
||||
use PhpOffice\PhpWord\Exception\Exception;
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Writer\PDF\AbstractRenderer;
|
||||
|
||||
/**
|
||||
* PDF Writer.
|
||||
@@ -71,6 +72,16 @@ class PDF
|
||||
// throw new Exception("PDF Rendering library has not been defined.");
|
||||
// }
|
||||
|
||||
return call_user_func_array([$this->renderer, $name], $arguments);
|
||||
return call_user_func_array([$this->getRenderer(), $name], $arguments);
|
||||
}
|
||||
|
||||
public function save(string $filename): void
|
||||
{
|
||||
$this->getRenderer()->save($filename);
|
||||
}
|
||||
|
||||
public function getRenderer(): AbstractRenderer
|
||||
{
|
||||
return $this->renderer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ abstract class AbstractRenderer extends HTML
|
||||
public function __construct(PhpWord $phpWord)
|
||||
{
|
||||
parent::__construct($phpWord);
|
||||
$this->isPdf = true;
|
||||
if ($this->includeFile != null) {
|
||||
$includeFile = Settings::getPdfRendererPath() . '/' . $this->includeFile;
|
||||
if (file_exists($includeFile)) {
|
||||
@@ -93,6 +94,12 @@ abstract class AbstractRenderer extends HTML
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
// Configuration
|
||||
$options = Settings::getPdfRendererOptions();
|
||||
if (!empty($options['font'])) {
|
||||
$this->setFont($options['font']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,7 +194,6 @@ abstract class AbstractRenderer extends HTML
|
||||
throw new Exception("Could not open file $filename for writing.");
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
$this->isPdf = true;
|
||||
|
||||
return $fileHandle;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
namespace PhpOffice\PhpWord\Writer\PDF;
|
||||
|
||||
use Dompdf\Dompdf as DompdfLib;
|
||||
use Dompdf\Options;
|
||||
use PhpOffice\PhpWord\Writer\WriterInterface;
|
||||
|
||||
/**
|
||||
@@ -42,15 +43,18 @@ class DomPDF extends AbstractRenderer implements WriterInterface
|
||||
*/
|
||||
protected function createExternalWriterInstance()
|
||||
{
|
||||
return new DompdfLib();
|
||||
$options = new Options();
|
||||
if ($this->getFont()) {
|
||||
$options->set('defaultFont', $this->getFont());
|
||||
}
|
||||
|
||||
return new DompdfLib($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save PhpWord to file.
|
||||
*
|
||||
* @param string $filename Name of the file to save as
|
||||
*/
|
||||
public function save($filename = null): void
|
||||
public function save(string $filename): void
|
||||
{
|
||||
$fileHandle = parent::prepareForSave($filename);
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ use PhpOffice\PhpWord\Writer\WriterInterface;
|
||||
*/
|
||||
class MPDF extends AbstractRenderer implements WriterInterface
|
||||
{
|
||||
public const SIMULATED_BODY_START = '<!-- simulated body start -->';
|
||||
private const BODY_TAG = '<body>';
|
||||
|
||||
/**
|
||||
* Overridden to set the correct includefile, only needed for MPDF 5.
|
||||
*
|
||||
@@ -46,21 +49,24 @@ class MPDF extends AbstractRenderer implements WriterInterface
|
||||
/**
|
||||
* Gets the implementation of external PDF library that should be used.
|
||||
*
|
||||
* @return Mpdf implementation
|
||||
* @return \Mpdf\Mpdf implementation
|
||||
*/
|
||||
protected function createExternalWriterInstance()
|
||||
{
|
||||
$mPdfClass = $this->getMPdfClassName();
|
||||
|
||||
return new $mPdfClass();
|
||||
$options = [];
|
||||
if ($this->getFont()) {
|
||||
$options['default_font'] = $this->getFont();
|
||||
}
|
||||
|
||||
return new $mPdfClass($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save PhpWord to file.
|
||||
*
|
||||
* @param string $filename Name of the file to save as
|
||||
*/
|
||||
public function save($filename = null): void
|
||||
public function save(string $filename): void
|
||||
{
|
||||
$fileHandle = parent::prepareForSave($filename);
|
||||
|
||||
@@ -82,7 +88,24 @@ class MPDF extends AbstractRenderer implements WriterInterface
|
||||
$pdf->setKeywords($docProps->getKeywords());
|
||||
$pdf->setCreator($docProps->getCreator());
|
||||
|
||||
$pdf->writeHTML($this->getContent());
|
||||
$html = $this->getContent();
|
||||
$bodyLocation = strpos($html, self::SIMULATED_BODY_START);
|
||||
if ($bodyLocation === false) {
|
||||
$bodyLocation = strpos($html, self::BODY_TAG);
|
||||
if ($bodyLocation !== false) {
|
||||
$bodyLocation += strlen(self::BODY_TAG);
|
||||
}
|
||||
}
|
||||
// Make sure first data presented to Mpdf includes body tag
|
||||
// (and any htmlpageheader/htmlpagefooter tags)
|
||||
// so that Mpdf doesn't parse it as content. Issue 2432.
|
||||
if ($bodyLocation !== false) {
|
||||
$pdf->WriteHTML(substr($html, 0, $bodyLocation));
|
||||
$html = substr($html, $bodyLocation);
|
||||
}
|
||||
foreach (explode("\n", $html) as $line) {
|
||||
$pdf->WriteHTML("$line\n");
|
||||
}
|
||||
|
||||
// Write to file
|
||||
fwrite($fileHandle, $pdf->output($filename, 'S'));
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\PDF;
|
||||
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Style;
|
||||
use PhpOffice\PhpWord\Writer\WriterInterface;
|
||||
use TCPDF as TCPDFBase;
|
||||
|
||||
/**
|
||||
* TCPDF writer.
|
||||
@@ -42,24 +46,56 @@ class TCPDF extends AbstractRenderer implements WriterInterface
|
||||
* @param string $unit Unit measure
|
||||
* @param string $paperSize Paper size
|
||||
*
|
||||
* @return \TCPDF implementation
|
||||
* @return TCPDFBase implementation
|
||||
*/
|
||||
protected function createExternalWriterInstance($orientation, $unit, $paperSize)
|
||||
{
|
||||
return new \TCPDF($orientation, $unit, $paperSize);
|
||||
$instance = new TCPDFBase($orientation, $unit, $paperSize);
|
||||
|
||||
if ($this->getFont()) {
|
||||
$instance->setFont($this->getFont(), $instance->getFontStyle(), $instance->getFontSizePt());
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwriteable function to allow user to extend TCPDF.
|
||||
* There should always be an AddPage call, preceded or followed
|
||||
* by code to customize TCPDF configuration.
|
||||
* The customization below sets vertical spacing
|
||||
* between paragaraphs when the user has
|
||||
* explicitly set those values to numeric in default style.
|
||||
*/
|
||||
protected function prepareToWrite(TCPDFBase $pdf): void
|
||||
{
|
||||
$pdf->AddPage();
|
||||
$customStyles = Style::getStyles();
|
||||
$normal = $customStyles['Normal'] ?? null;
|
||||
if ($normal instanceof Style\Paragraph) {
|
||||
$before = $normal->getSpaceBefore();
|
||||
$after = $normal->getSpaceAfter();
|
||||
if (is_numeric($before) && is_numeric($after)) {
|
||||
$height = $normal->getLineHeight() ?? '';
|
||||
$pdf->setHtmlVSpace([
|
||||
'p' => [
|
||||
['n' => $before, 'h' => $height],
|
||||
['n' => $after, 'h' => $height],
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save PhpWord to file.
|
||||
*
|
||||
* @param string $filename Name of the file to save as
|
||||
*/
|
||||
public function save($filename = null): void
|
||||
public function save(string $filename): void
|
||||
{
|
||||
$fileHandle = parent::prepareForSave($filename);
|
||||
|
||||
// PDF settings
|
||||
$paperSize = 'A4';
|
||||
$paperSize = strtoupper(Settings::getDefaultPaper());
|
||||
$orientation = 'P';
|
||||
|
||||
// Create PDF
|
||||
@@ -67,8 +103,8 @@ class TCPDF extends AbstractRenderer implements WriterInterface
|
||||
$pdf->setFontSubsetting(false);
|
||||
$pdf->setPrintHeader(false);
|
||||
$pdf->setPrintFooter(false);
|
||||
$pdf->AddPage();
|
||||
$pdf->SetFont($this->getFont());
|
||||
$this->prepareToWrite($pdf);
|
||||
$pdf->writeHTML($this->getContent());
|
||||
|
||||
// Write document properties
|
||||
|
||||
@@ -35,8 +35,6 @@ class RTF extends AbstractWriter implements WriterInterface
|
||||
|
||||
/**
|
||||
* Create new instance.
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\PhpWord $phpWord
|
||||
*/
|
||||
public function __construct(?PhpWord $phpWord = null)
|
||||
{
|
||||
@@ -56,10 +54,8 @@ class RTF extends AbstractWriter implements WriterInterface
|
||||
|
||||
/**
|
||||
* Save content to file.
|
||||
*
|
||||
* @param string $filename
|
||||
*/
|
||||
public function save($filename = null): void
|
||||
public function save(string $filename): void
|
||||
{
|
||||
$this->writeFile($this->openFile($filename), $this->getContent());
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ use PhpOffice\PhpWord\Style;
|
||||
use PhpOffice\PhpWord\Style\Font as FontStyle;
|
||||
use PhpOffice\PhpWord\Style\Paragraph as ParagraphStyle;
|
||||
use PhpOffice\PhpWord\Writer\AbstractWriter;
|
||||
use PhpOffice\PhpWord\Writer\HTML\Element\AbstractElement as HTMLAbstractElement;
|
||||
use PhpOffice\PhpWord\Writer\RTF\Style\Font as FontStyleWriter;
|
||||
use PhpOffice\PhpWord\Writer\RTF\Style\Paragraph as ParagraphStyleWriter;
|
||||
|
||||
@@ -34,8 +33,36 @@ use PhpOffice\PhpWord\Writer\RTF\Style\Paragraph as ParagraphStyleWriter;
|
||||
*
|
||||
* @since 0.11.0
|
||||
*/
|
||||
abstract class AbstractElement extends HTMLAbstractElement
|
||||
abstract class AbstractElement
|
||||
{
|
||||
/**
|
||||
* Parent writer.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
|
||||
*/
|
||||
protected $parentWriter;
|
||||
|
||||
/**
|
||||
* Element.
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Element\AbstractElement
|
||||
*/
|
||||
protected $element;
|
||||
|
||||
/**
|
||||
* Without paragraph.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $withoutP = false;
|
||||
|
||||
/**
|
||||
* Write element.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function write();
|
||||
|
||||
/**
|
||||
* Font style.
|
||||
*
|
||||
@@ -50,10 +77,16 @@ abstract class AbstractElement extends HTMLAbstractElement
|
||||
*/
|
||||
protected $paragraphStyle;
|
||||
|
||||
public function __construct(AbstractWriter $parentWriter, Element $element, $withoutP = false)
|
||||
{
|
||||
parent::__construct($parentWriter, $element, $withoutP);
|
||||
/**
|
||||
* @var \PhpOffice\PhpWord\Escaper\EscaperInterface
|
||||
*/
|
||||
protected $escaper;
|
||||
|
||||
public function __construct(AbstractWriter $parentWriter, Element $element, bool $withoutP = false)
|
||||
{
|
||||
$this->parentWriter = $parentWriter;
|
||||
$this->element = $element;
|
||||
$this->withoutP = $withoutP;
|
||||
$this->escaper = new Rtf();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\RTF\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Writer\HTML\Element\Container as HTMLContainer;
|
||||
use PhpOffice\PhpWord\Element\AbstractContainer as ContainerElement;
|
||||
|
||||
/**
|
||||
* Container element RTF writer.
|
||||
*
|
||||
* @since 0.11.0
|
||||
*/
|
||||
class Container extends HTMLContainer
|
||||
class Container extends AbstractElement
|
||||
{
|
||||
/**
|
||||
* Namespace; Can't use __NAMESPACE__ in inherited class (RTF).
|
||||
@@ -32,4 +32,33 @@ class Container extends HTMLContainer
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = 'PhpOffice\\PhpWord\\Writer\\RTF\\Element';
|
||||
|
||||
/**
|
||||
* Write container.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$container = $this->element;
|
||||
if (!$container instanceof ContainerElement) {
|
||||
return '';
|
||||
}
|
||||
$containerClass = substr(get_class($container), strrpos(get_class($container), '\\') + 1);
|
||||
$withoutP = in_array($containerClass, ['TextRun', 'Footnote', 'Endnote']) ? true : false;
|
||||
$content = '';
|
||||
|
||||
$elements = $container->getElements();
|
||||
foreach ($elements as $element) {
|
||||
$elementClass = get_class($element);
|
||||
$writerClass = str_replace('PhpOffice\\PhpWord\\Element', $this->namespace, $elementClass);
|
||||
if (class_exists($writerClass)) {
|
||||
/** @var AbstractElement $writer Type hint */
|
||||
$writer = new $writerClass($this->parentWriter, $element, $withoutP);
|
||||
$content .= $writer->write();
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\RTF\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Element\Field as ElementField;
|
||||
|
||||
/**
|
||||
* Field element writer.
|
||||
*
|
||||
* Note: for now, only date, page and numpages fields are implemented for RTF.
|
||||
* Note: for now, only date, page, numpages and filename fields are implemented for RTF.
|
||||
*/
|
||||
class Field extends Text
|
||||
{
|
||||
@@ -30,7 +32,7 @@ class Field extends Text
|
||||
public function write()
|
||||
{
|
||||
$element = $this->element;
|
||||
if (!$element instanceof \PhpOffice\PhpWord\Element\Field) {
|
||||
if (!$element instanceof ElementField) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -66,7 +68,18 @@ class Field extends Text
|
||||
return 'NUMPAGES';
|
||||
}
|
||||
|
||||
protected function writeDate(\PhpOffice\PhpWord\Element\Field $element)
|
||||
protected function writeFilename(ElementField $element): string
|
||||
{
|
||||
$content = 'FILENAME';
|
||||
$options = $element->getOptions();
|
||||
if ($options != null && in_array('Path', $options)) {
|
||||
$content .= ' \\\\p';
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
protected function writeDate(ElementField $element)
|
||||
{
|
||||
$content = '';
|
||||
$content .= 'DATE';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user