diff --git a/docs/changes/1.1.0.md b/docs/changes/1.1.0.md index 81ba6ae1e..103d901a0 100644 --- a/docs/changes/1.1.0.md +++ b/docs/changes/1.1.0.md @@ -17,9 +17,22 @@ - PowerPoint2007 Reader - PowerPoint2007 Writer - PowerPoint2007 Writer: Enable style and position of a Placeholder - [@qmachard](https://github.com/qmachard) in [#787](https://github.com/PHPOffice/PHPPresentation/pull/787) +- PowerPoint2007 Reader: Added support for thumbnail - [@devX2712](https://github.com/devX2712) in [#788](https://github.com/PHPOffice/PHPPresentation/pull/787) ## Improvements - Slide : Raised max value for identifier rand call - [@Scheissy](https://github.com/Scheissy) in [#777](https://github.com/PHPOffice/PHPPresentation/pull/777) +- Document Properties : Support for Revision & Status - [@devX2712](https://github.com/devX2712) in [#788](https://github.com/PHPOffice/PHPPresentation/pull/787) + - PowerPoint2007 Reader + - PowerPoint2007 Writer +- Presentation Properties : Added support to define content of the thumbnail - [@devX2712](https://github.com/devX2712) in [#788](https://github.com/PHPOffice/PHPPresentation/pull/787) +- Font : Support for Strikethrough mode - [@devX2712](https://github.com/devX2712) in [#788](https://github.com/PHPOffice/PHPPresentation/pull/787) + - PowerPoint2007 Reader + - PowerPoint2007 Writer +- Font : Support for Pitch Family, Charset & Panose - [@devX2712](https://github.com/devX2712) in [#788](https://github.com/PHPOffice/PHPPresentation/pull/787) + - PowerPoint2007 Reader + - PowerPoint2007 Writer +(@todo Doc) +- Font : Replaced Superscript/Subscript by baseline in PowerPoint2007 Writer - [@devX2712](https://github.com/devX2712) in [#788](https://github.com/PHPOffice/PHPPresentation/pull/787) ## Bugfixes diff --git a/docs/usage/presentation.md b/docs/usage/presentation.md index 03080aa1c..a06e0958b 100644 --- a/docs/usage/presentation.md +++ b/docs/usage/presentation.md @@ -62,6 +62,8 @@ $properties->setCreated(mktime(0, 0, 0, 3, 12, 2014)); $properties->setModified(mktime(0, 0, 0, 3, 14, 2014)); $properties->setSubject('My subject'); $properties->setKeywords('my, key, word'); +$properties->setStatus('Work in Progress'); +$properties->setRevision('Version 1.2.3'); ``` ### Custom Properties @@ -203,16 +205,44 @@ echo $properties->getSlideshowType(); You can define the thumbnail of the presentation with the method `setThumbnailPath`. + +#### From a file ``` php getPresentationProperties(); // Set path of the thumbnail -$properties->setThumbnailPath(__DIR__.'\resources\phppowerpoint_logo.gif'); +$properties->setThumbnailPath( + __DIR__.'\resources\phppowerpoint_logo.gif', + PresentationProperties::THUMBNAIL_FILE +); // Get path of the thumbnail echo $properties->getThumbnailPath(); +// Get content of the thumbnail +echo $properties->getThumbnail(); +``` + +#### From the content of the file +``` php +getPresentationProperties(); +// Set path of the thumbnail +$properties->setThumbnailPath( + '', + PresentationProperties::THUMBNAIL_DATA, + file_get_contents(__DIR__.'\resources\phppowerpoint_logo.gif') +); +// Get content of the thumbnail +echo $properties->getThumbnail(); ``` ### Zoom diff --git a/docs/usage/styles.md b/docs/usage/styles.md index e9ff72c60..a21efdc8e 100644 --- a/docs/usage/styles.md +++ b/docs/usage/styles.md @@ -97,12 +97,24 @@ echo $alignment->isRTL(); - `name` - `bold` - `italic` -- `superScript` -- `subScript` +- `superScript` (deprecated) +- `subScript` (deprecated) - `underline` - `strikethrough` - `color` -- `capitalization` +- `pitchFamily` +- `charset` + +### Baseline + +The baseline set the position relative to the line. +The value is a percentage. + +You can use some predefined values : + +* `Font::BASELINE_SUPERSCRIPT` (= 300000 = 300%) +* `Font::BASELINE_SUBSCRIPT` (= -250000 = -250%) + ### Capitalization @@ -145,6 +157,23 @@ $font->setFormat(Font::FORMAT_EAST_ASIAN); // Get format of font echo $font->getFormat(); ``` + +### Panose +The support of Panose 1.0 is only used. + +``` php +setPanose('4494D72242'); +// Get panose of font +echo $font->getPanose(); +``` + ## Bullet - `bulletType` diff --git a/samples/Sample_Header.php b/samples/Sample_Header.php index 61796fe6f..ea250e96a 100644 --- a/samples/Sample_Header.php +++ b/samples/Sample_Header.php @@ -326,7 +326,7 @@ protected function displayPhpPresentationInfo(PhpPresentation $oPHPPpt): void } } $oNote = $oSlide->getNote(); - if ($oNote->getShapeCollection()->count() > 0) { + if (count($oNote->getShapeCollection()) > 0) { $this->append('
Notes
'); foreach ($oNote->getShapeCollection() as $oShape) { if ($oShape instanceof RichText) { @@ -442,6 +442,7 @@ protected function displayShapeInfo(AbstractShape $oShape): void $this->append('Italic : ' . ($oRichText->getFont()->isItalic() ? 'Y' : 'N') . ' - '); $this->append('Underline : Underline::' . $this->getConstantName('\PhpOffice\PhpPresentation\Style\Font', $oRichText->getFont()->getUnderline()) . ' - '); $this->append('Strikethrough : ' . ($oRichText->getFont()->isStrikethrough() ? 'Y' : 'N') . ' - '); + $this->append('Baseline : ' . $oRichText->getFont()->getBaseline() . ' - '); $this->append('SubScript : ' . ($oRichText->getFont()->isSubScript() ? 'Y' : 'N') . ' - '); $this->append('SuperScript : ' . ($oRichText->getFont()->isSuperScript() ? 'Y' : 'N')); $this->append(''); diff --git a/src/PhpPresentation/AbstractShape.php b/src/PhpPresentation/AbstractShape.php index 176247149..1d1712c40 100644 --- a/src/PhpPresentation/AbstractShape.php +++ b/src/PhpPresentation/AbstractShape.php @@ -102,12 +102,6 @@ abstract class AbstractShape implements ComparableInterface */ protected $placeholder; - /** - * List of effect apply to shape - * @var array \PhpOffice\PhpPresentation\Style\Effect[] - */ - protected ?array $effectCollection = null; - /** * Hash index * @@ -131,7 +125,6 @@ public function __construct() $this->fill = new Fill(); $this->shadow = new Shadow(); $this->border = new Border(); - $this->effectCollection = null; $this->border->setLineStyle(Style\Border::LINE_NONE); } @@ -143,12 +136,10 @@ public function __clone() { $this->container = null; $this->name = $this->name; + $this->border = clone $this->border; if (isset($this->fill)) { $this->fill = clone $this->fill; } - if (isset($this->border)) { - $this->border = clone $this->border; - } if (isset($this->shadow)) { $this->shadow = clone $this->shadow; } @@ -158,11 +149,6 @@ public function __clone() if (isset($this->hyperlink)) { $this->hyperlink = clone $this->hyperlink; } - // Clone each effect - if (isset($this->effectCollection)) { - foreach ($this->effectCollection as &$effect) { - $effect = clone $effect; - }} } /** @@ -186,21 +172,18 @@ public function setContainer(?ShapeContainerInterface $pValue = null, $pOverride // Add drawing to ShapeContainerInterface $this->container = $pValue; if (null !== $this->container) { - $this->container->getShapeCollection()->append($this); + $this->container->addShape($this); } } else { if ($pOverrideOld) { // Remove drawing from old ShapeContainerInterface - $iterator = $this->container->getShapeCollection()->getIterator(); - - while ($iterator->valid()) { - if ($iterator->current()->getHashCode() == $this->getHashCode()) { - $this->container->getShapeCollection()->offsetUnset($iterator->key()); + foreach ($this->container->getShapeCollection() as $key => $shape) { + if ($shape->getHashCode() == $this->getHashCode()) { + $this->container->getShapeCollection()->unsetShape($key); $this->container = null; break; } - $iterator->next(); } // Set new \PhpOffice\PhpPresentation\Slide @@ -215,21 +198,16 @@ public function setContainer(?ShapeContainerInterface $pValue = null, $pOverride /** * Get Name - * - * @return string */ - public function getName() + public function getName(): string { return $this->name; } /** * Set Name - * - * @param string $pValue - * @return \PhpOffice\PhpPresentation\Shape\AbstractGraphic */ - public function setName($pValue = '') + public function setName(string $pValue = ''): self { $this->name = $pValue; return $this; @@ -423,46 +401,6 @@ public function setHyperlink(?Hyperlink $pHyperlink = null): self return $this; } - - /** - * Add an effect to the shpae - * - * @param \PhpOffice\PhpPresentation\Style\Effect $effect - * @return $this - */ - public function addEffect(Shape\Effect $effect) - { - if (!isset($this->effectCollection)) { - $this->effectCollection = array(); - } - $this->effectCollection[] = $effect; - return $this; - } - - /** - * Get the effect collection - * - * @return array \PhpOffice\PhpPresentation\Style\Effect[] - */ - public function getEffectCollection():?array - { - return $this->effectCollection; - } - - /** - * Set the effect collection - * - * @param array \PhpOffice\PhpPresentation\Style\Effect $effectCollection - * @return $this - */ - public function setEffectCollection(array $effectCollection) - { - if ( isset($effectCollection) - && is_array($effectCollection)) { - $this->effectCollection = $effectCollection; - } - return $this; - } /** * Get hash code. diff --git a/src/PhpPresentation/DocumentProperties.php b/src/PhpPresentation/DocumentProperties.php index c6a24e453..96d545b84 100644 --- a/src/PhpPresentation/DocumentProperties.php +++ b/src/PhpPresentation/DocumentProperties.php @@ -102,11 +102,18 @@ class DocumentProperties private $company; /** - * revision + * Revision. * * @var string */ private $revision; + + /** + * Status. + * + * @var string + */ + private $status; /** * Custom Properties. @@ -116,14 +123,7 @@ class DocumentProperties private $customProperties = []; /** - * status - * - * @var string - */ - private $status; - - /** - * Create a new \PhpOffice\PhpPresentation\DocumentProperties + * Create a new \PhpOffice\PhpPresentation\DocumentProperties. */ public function __construct() { @@ -139,7 +139,7 @@ public function __construct() $this->category = ''; $this->company = 'Microsoft Corporation'; $this->revision = ''; - $this->status = ''; + $this->status = ''; } /** @@ -479,7 +479,7 @@ public function getRevision(): string } /** - * Set Revision + * Set Revision. */ public function setRevision(string $pValue = ''): self { @@ -489,22 +489,17 @@ public function setRevision(string $pValue = ''): self } /** - * Get Status - * - * @return string + * Get Status. */ - public function getStatus() + public function getStatus(): string { return $this->status; } /** - * Set Status - * - * @param string $pValue - * @return \PhpOffice\PhpPresentation\DocumentProperties + * Set Status. */ - public function setStatus($pValue = '') + public function setStatus(string $pValue = ''): self { $this->status = $pValue; diff --git a/src/PhpPresentation/Exception/InvalidParameterException.php b/src/PhpPresentation/Exception/InvalidParameterException.php index 961809623..502705e67 100644 --- a/src/PhpPresentation/Exception/InvalidParameterException.php +++ b/src/PhpPresentation/Exception/InvalidParameterException.php @@ -21,12 +21,17 @@ class InvalidParameterException extends PhpPresentationException { - public function __construct(string $parameter, string $value) + public function __construct(string $parameter, string $value, string $error = null) { - parent::__construct(sprintf( + $message = sprintf( 'The parameter %s can\'t have the value "%s"', $parameter, $value - )); + ); + if ($error) { + $message = sprintf('%s (Validation: %s)', $message, $error); + } + + parent::__construct($message); } } diff --git a/src/PhpPresentation/PresentationProperties.php b/src/PhpPresentation/PresentationProperties.php index 63eca8fb5..ff2cc5aaa 100644 --- a/src/PhpPresentation/PresentationProperties.php +++ b/src/PhpPresentation/PresentationProperties.php @@ -30,8 +30,8 @@ class PresentationProperties public const VIEW_SLIDE_SORTER = 'sldSorterView'; public const VIEW_SLIDE_THUMBNAIL = 'sldThumbnailView'; - public const THUMBNAIL_FILE = 'file'; // Thumbnail path is out of PPT - public const THUMBNAIL_ZIP = 'zip'; // Thumbnail path point to an image store into file loaded + public const THUMBNAIL_FILE = 'file'; + public const THUMBNAIL_DATA = 'data'; /** * @var array @@ -72,17 +72,17 @@ class PresentationProperties */ protected $markAsFinal = false; - /* - * @var string Define the thumbnail content (if content into zip file) + /** + * @var string|null Define the thumbnail content (if content into zip file) */ protected $thumbnail = null; - /* - * @var string Define the thumbnail place + /** + * @var string|null Define the thumbnail place */ - protected $thumbnailPath = ''; + protected $thumbnailPath = null; - /* + /** * @var string Define if thumbnail is out of PPT or previouly store into PPT */ protected $thumbnailType = self::THUMBNAIL_FILE; @@ -130,36 +130,38 @@ public function getThumbnailPath(): ?string } /** - * Return the content of thumbnail - * - * @return binary Content of image + * Return the content of thumbnail. */ - public function getThumbnail() + public function getThumbnail(): ?string { // Return content of local file if ($this->getThumbnailType() == self::THUMBNAIL_FILE) { - if (file_exists($this->getThumbnailPath())) + if ($this->getThumbnailPath()) { return file_get_contents($this->getThumbnailPath()); + } + + return null; } + // Return content of image stored into zip file - if ($this->getThumbnailType() == self::THUMBNAIL_ZIP) { + if ($this->getThumbnailType() == self::THUMBNAIL_DATA) { return $this->thumbnail; } - // Return null if no thumbnail + return null; } /** * Define the path for the thumbnail file / preview picture. */ - public function setThumbnailPath(string $path = '', $type = self::THUMBNAIL_FILE, $content = null) + public function setThumbnailPath(string $path = '', string $type = self::THUMBNAIL_FILE, string $content = null): self { - if (file_exists($path) && ($type == self::THUMBNAIL_FILE)) { + if (file_exists($path) && $type == self::THUMBNAIL_FILE) { $this->thumbnailPath = $path; $this->thumbnailType = $type; } - if (($path != '') && ($type == self::THUMBNAIL_ZIP)) { - $this->thumbnailPath = $path; + if ($content != '' && $type == self::THUMBNAIL_DATA) { + $this->thumbnailPath = ''; $this->thumbnailType = $type; $this->thumbnail = $content; } @@ -168,10 +170,9 @@ public function setThumbnailPath(string $path = '', $type = self::THUMBNAIL_FILE } /** - * Return the thumbnail type - * @return string + * Return the thumbnail type. */ - public function getThumbnailType() + public function getThumbnailType(): string { return $this->thumbnailType; } diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index e619a2607..0f670c9b5 100644 --- a/src/PhpPresentation/Reader/PowerPoint2007.php +++ b/src/PhpPresentation/Reader/PowerPoint2007.php @@ -51,6 +51,7 @@ use PhpOffice\PhpPresentation\Style\Fill; use PhpOffice\PhpPresentation\Style\Font; use PhpOffice\PhpPresentation\Style\SchemeColor; +use PhpOffice\PhpPresentation\Style\Shadow; use PhpOffice\PhpPresentation\Style\TextStyle; use ZipArchive; @@ -230,7 +231,7 @@ protected function loadDocumentProperties(string $sPart): void '/cp:coreProperties/dcterms:modified' => 'setModified', '/cp:coreProperties/cp:revision' => 'setRevision', '/cp:coreProperties/cp:contentStatus' => 'setStatus', - ); + ]; $oProperties = $this->oPhpPresentation->getDocumentProperties(); foreach ($arrayProperties as $path => $property) { $oElement = $xmlReader->getElement($path); @@ -248,27 +249,23 @@ protected function loadDocumentProperties(string $sPart): void /** * Read information of the document thumbnail - * @param string $sPart Content of XML file for retrieving data */ - protected function loadThumbnailProperties($sPart) + protected function loadThumbnailProperties(string $sPart): void { $xmlReader = new XMLReader(); - if ($xmlReader->getDomFromString($sPart)) { - $oElement = $xmlReader->getElement('*[@Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"]'); - if ($oElement instanceof \DOMElement) { + $xmlReader->getDomFromString($sPart); + + $oElement = $xmlReader->getElement('*[@Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"]'); + if ($oElement instanceof \DOMElement) { $path = $oElement->getAttribute('Target'); $this->oPhpPresentation - ->getPresentationProperties() - ->setThumbnailPath($path - , \PhpOffice\PhpPresentation\PresentationProperties::THUMBNAIL_ZIP - , $this->oZip->getFromName($path)); - } - } + ->getPresentationProperties() + ->setThumbnailPath('', PresentationProperties::THUMBNAIL_DATA, $this->oZip->getFromName($path)); + }} } /** - * Read Custom Properties - * @param string $sPart + * Read Custom Properties. */ protected function loadCustomProperties(string $sPart): void { @@ -878,79 +875,60 @@ protected function loadShapeDrawing(XMLReader $document, DOMElement $node, Abstr } } // Load shape effects - $oEffect = $document->getElement('p:spPr/a:effectLst', $node); - if ($oEffect instanceof \DOMElement) { - $aEffect = $this->loadEffect($document, $oEffect); - if (isset($aEffect) && is_array($aEffect)) { - $oShape->setEffectCollection($aEffect); - } + $oElement = $document->getElement('p:spPr/a:effectLst', $node); + if ($oElement instanceof DOMElement) { + $oShape->setShadow( + $this->loadShadow($document, $oElement) + ); } $oSlide->addShape($oShape); } /** - * Load Effect for shape or paragraph - * - * @param XMLReader $document - * @param \DOMElement $node - * @return array \PhpOffice\PhpPresentation\Style\Effect[] + * Load Shadow for shape or paragraph. */ - protected function loadEffect(XMLReader $document, \DOMElement $nodeEffect) + protected function loadShadow(XMLReader $document, DOMElement $node): ?Shadow { - $aEffect = null; - if ($nodeEffect instanceof \DOMElement) { - - $aNodes = $document->getElements('*', $nodeEffect); - foreach ($aNodes as $node) { - - $type = explode(':', $node->tagName); - $type = array_pop($type); - if ( $type == 'outerShdw' - || $type == 'innerShdw') { -// @TODO || $type == 'reflection') { - - // Create a new effect - $effect = new \PhpOffice\PhpPresentation\Style\Effect($type); - // load blur radius - if ($node->hasAttribute('blurRad')) { - $effect->setBlurRadius(CommonDrawing::emuToPixels($node->getAttribute('blurRad'))); - } - // load distance - if ($node->hasAttribute('dist')) { - $effect->setDistance(CommonDrawing::emuToPixels($node->getAttribute('dist'))); - } - // load direction - if ($node->hasAttribute('dir')) { - $effect->setDirection(CommonDrawing::angleToDegrees($node->getAttribute('dir'))); - } - // load alignment - if ($node->hasAttribute('algn')) { - $effect->setAlignment($node->getAttribute('algn')); - } - - // Get color define by prstClr - $oSubElement = $document->getElement('a:prstClr', $node); - if ($oSubElement instanceof \DOMElement && $oSubElement->hasAttribute('val')) { - $oColor = new Color(); - $oColor->setRGB($oSubElement->getAttribute('val')); - $effect->setColor($oColor); - // Get Alpha - $oSubElt = $document->getElement('a:alpha', $oSubElement); - if ($oSubElt instanceof \DOMElement && $oSubElt->hasAttribute('val')) { - $effect->setAlpha((int)$oSubElt->getAttribute('val') / 1000); - } - } - // Load reflection atributs -// @TODO future implementation - if ($node->tagName == 'a:reflection') { - } - - if (!isset($aEffect)) $aEffect = array(); - $aEffect[] = $effect; - } - } + if ($node instanceof DOMElement) { + $aNodes = $document->getElements('*', $node); + foreach ($aNodes as $nodeShadow) { + $type = explode(':', $nodeShadow->tagName); + $type = array_pop($type); + if ($type == Shadow::TYPE_SHADOW_INNER || $type == Shadow::TYPE_SHADOW_OUTER || $type == Shadow::TYPE_REFLECTION) { + $oShadow = new Shadow($type); + if ($nodeShadow->hasAttribute('blurRad')) { + $oShadow->setBlurRadius(CommonDrawing::emuToPixels((int) $nodeShadow->getAttribute('blurRad'))); + } + if ($nodeShadow->hasAttribute('dist')) { + $oShadow->setDistance(CommonDrawing::emuToPixels((int) $nodeShadow->getAttribute('dist'))); + } + if ($nodeShadow->hasAttribute('dir')) { + $oShadow->setDirection((int) CommonDrawing::angleToDegrees((int) $nodeShadow->getAttribute('dir'))); + } + if ($nodeShadow->hasAttribute('algn')) { + $oShadow->setAlignment($node->getAttribute('algn')); + } + + // Get color define by prstClr + $oSubElement = $document->getElement('a:prstClr', $nodeShadow); + if ($oSubElement instanceof \DOMElement && $oSubElement->hasAttribute('val')) { + $oColor = new Color(); + $oColor->setRGB($oSubElement->getAttribute('val')); + + $oSubElt = $document->getElement('a:alpha', $oSubElement); + if ($oSubElt instanceof \DOMElement && $oSubElt->hasAttribute('val')) { + $oColor->setAlpha((int)$oSubElt->getAttribute('val') / 1000); + } + + $oShadow->setColor($oColor); + } + + return $oShadow; + } + } } - return $aEffect; + + return null; } /** @@ -1004,33 +982,34 @@ protected function loadShapeRichText(XMLReader $document, DOMElement $node, $oSl } // Load shape effects - $oEffect = $document->getElement('p:spPr/a:effectLst', $node); - if ($oEffect instanceof \DOMElement) { - $aEffect = $this->loadEffect($document, $oEffect); - if (isset($aEffect) && is_array($aEffect)) { - $oShape->setEffectCollection($aEffect); - } + $oElement = $document->getElement('p:spPr/a:effectLst', $node); + if ($oElement instanceof DOMElement) { + $oShape->setShadow( + $this->loadShadow($document, $oElement) + ); } -// FBU-20210202+ Read body definitions + // FBU-20210202+ Read body definitions $bodyPr = $document->getElement('p:txBody/a:bodyPr', $node); - if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('lIns')) { - $oShape->setInsetLeft((int)$bodyPr->getAttribute('lIns')); - } - if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('tIns')) { - $oShape->setInsetTop((int)$bodyPr->getAttribute('tIns')); - } - if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('rIns')) { - $oShape->setInsetRight((int)$bodyPr->getAttribute('rIns')); - } - if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('bIns')) { - $oShape->setInsetBottom((int)$bodyPr->getAttribute('bIns')); - } - if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('anchor')) { - $oShape->setVerticalAlignment($bodyPr->getAttribute('anchor')); - } - if (($bodyPr instanceof \DOMElement) && $bodyPr->hasAttribute('anchorCtr')) { - $oShape->setVerticalAlignCenter((int)$bodyPr->getAttribute('anchorCtr')); + if ($bodyPr instanceof DOMElement) { + if ($bodyPr->hasAttribute('lIns')) { + $oShape->setInsetLeft((int)$bodyPr->getAttribute('lIns')); + } + if ($bodyPr->hasAttribute('tIns')) { + $oShape->setInsetTop((int)$bodyPr->getAttribute('tIns')); + } + if ($bodyPr->hasAttribute('rIns')) { + $oShape->setInsetRight((int)$bodyPr->getAttribute('rIns')); + } + if ($bodyPr->hasAttribute('bIns')) { + $oShape->setInsetBottom((int)$bodyPr->getAttribute('bIns')); + } + if ($bodyPr->hasAttribute('anchor')) { + $oShape->setVerticalAlignment($bodyPr->getAttribute('anchor')); + } + if ($bodyPr->hasAttribute('anchorCtr')) { + $oShape->setVerticalAlignCenter((int)$bodyPr->getAttribute('anchorCtr')); + } } $arrayElements = $document->getElements('p:txBody/a:p', $node); @@ -1042,8 +1021,9 @@ protected function loadShapeRichText(XMLReader $document, DOMElement $node, $oSl $oElement = $document->getElement('p:spPr', $node); if ($oElement instanceof \DOMElement) { - $oFill = $this->loadStyleFill($document, $oElement); - $oShape->setFill($oFill); + $oShape->setFill( + $this->loadStyleFill($document, $oElement) + ); } if (count($oShape->getParagraphs()) > 0) { @@ -1316,11 +1296,7 @@ protected function loadParagraph(XMLReader $document, DOMElement $oElement, $oSh $oText->setLanguage($oElementrPr->getAttribute('lang')); } if ($oElementrPr->hasAttribute('baseline')) { - if ((int)$oElementrPr->getAttribute('baseline')>0) { - $oText->getFont()->setSuperScript((int)$oElementrPr->getAttribute('baseline')); - } else if ((int)$oElementrPr->getAttribute('baseline')<0) { - $oText->getFont()->setSubScript((int)$oElementrPr->getAttribute('baseline')); - } + $oText->getFont()->setBaseline((int) $oElementrPr->getAttribute('baseline')); } // Color $oElementSrgbClr = $document->getElement('a:solidFill/a:srgbClr', $oElementrPr); @@ -1358,28 +1334,27 @@ protected function loadParagraph(XMLReader $document, DOMElement $oElement, $oSh } // Font definition $oElementFont = $document->getElement('a:latin', $oElementrPr); - if (is_object($oElementFont) && $oElementFont->hasAttribute('typeface')) { - $oText->getFont()->setName($oElementFont->getAttribute('typeface')); - } - if (($oElementFont instanceof \DOMElement) && $oElementFont->hasAttribute('panose')) { - $oText->getFont()->setPanose($oElementFont->getAttribute('panose')); - } - if (($oElementFont instanceof \DOMElement) && $oElementFont->hasAttribute('pitchFamily')) { - $oText->getFont()->setPitchFamily($oElementFont->getAttribute('pitchFamily')); - } - if (($oElementFont instanceof \DOMElement) && $oElementFont->hasAttribute('charset')) { - $oText->getFont()->setCharset($oElementFont->getAttribute('charset')); + if ($oElementFont instanceof \DOMElement) { + if ($oElementFont->hasAttribute('typeface')) { + $oText->getFont()->setName($oElementFont->getAttribute('typeface')); + } + if ($oElementFont->hasAttribute('panose')) { + $oText->getFont()->setPanose($oElementFont->getAttribute('panose')); + } + if ($oElementFont->hasAttribute('pitchFamily')) { + $oText->getFont()->setPitchFamily((int) $oElementFont->getAttribute('pitchFamily')); + } + if ($oElementFont->hasAttribute('charset')) { + $oText->getFont()->setCharset((int) $oElementFont->getAttribute('charset')); + } } // Load shape effects - $oEffect = $document->getElement('a:effectLst', $oElementrPr); - if ($oEffect instanceof \DOMElement) { - $aEffect = $this->loadEffect($document, $oEffect); - if (isset($aEffect) && is_array($aEffect)) { - $oText->setEffectCollection($aEffect); - } + $oElementShadow = $document->getElement('a:effectLst', $oElementrPr); + if ($oElementShadow instanceof \DOMElement) { + $oText->setShadow( + $this->loadShadow($document, $oElementShadow) + ); } - //} else { - // $oText = $oParagraph->createText(); $oSubSubElement = $document->getElement('a:t', $oSubElement); $oText->setText($oSubSubElement->nodeValue); diff --git a/src/PhpPresentation/Reader/PowerPoint97.php b/src/PhpPresentation/Reader/PowerPoint97.php index 6189edb08..4ef8fc91c 100644 --- a/src/PhpPresentation/Reader/PowerPoint97.php +++ b/src/PhpPresentation/Reader/PowerPoint97.php @@ -1796,7 +1796,7 @@ private function readRecordOfficeArtSpgrContainer($stream, $pos, $bInGroup = fal $arrayIdxSlide = array_flip($this->arrayNotes); if ($this->currentNote > 0 && isset($arrayIdxSlide[$this->currentNote])) { $oSlide = $this->oPhpPresentation->getSlide($arrayIdxSlide[$this->currentNote]); - if (0 == $oSlide->getNote()->getShapeCollection()->count()) { + if (0 == count($oSlide->getNote()->getShapeCollection())) { $oSlide->getNote()->addShape($fileBlock['shape']); } } diff --git a/src/PhpPresentation/Reader/Serialized.php b/src/PhpPresentation/Reader/Serialized.php index 208c28325..fce5cfc0c 100644 --- a/src/PhpPresentation/Reader/Serialized.php +++ b/src/PhpPresentation/Reader/Serialized.php @@ -92,7 +92,7 @@ private function loadSerialized(string $pFilename): PhpPresentation // Update media links for ($i = 0; $i < $file->getSlideCount(); ++$i) { - for ($j = 0; $j < $file->getSlide($i)->getShapeCollection()->count(); ++$j) { + for ($j = 0; $j < count($file->getSlide($i)->getShapeCollection()); ++$j) { if ($file->getSlide($i)->getShapeCollection()->offsetGet($j) instanceof AbstractDrawingAdapter) { $imgTemp = $file->getSlide($i)->getShapeCollection()->offsetGet($j); $imgPath = 'zip://' . $pFilename . '#media/' . $imgTemp->getImageIndex() . '/' . pathinfo($imgTemp->getPath(), PATHINFO_BASENAME); diff --git a/src/PhpPresentation/Shape/AbstractGraphic.php b/src/PhpPresentation/Shape/AbstractGraphic.php index f8b464f51..064e32a9e 100644 --- a/src/PhpPresentation/Shape/AbstractGraphic.php +++ b/src/PhpPresentation/Shape/AbstractGraphic.php @@ -41,13 +41,6 @@ abstract class AbstractGraphic extends AbstractShape implements ComparableInterf */ private $imageIndex = 0; - /** - * Name. - * - * @var string - */ - protected $name; - /** * Description. * @@ -105,30 +98,6 @@ public function getImageIndex() return $this->imageIndex; } - /** - * Get Name. - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set Name. - * - * @param string $pValue - * - * @return $this - */ - public function setName($pValue = '') - { - $this->name = $pValue; - - return $this; - } - /** * Get Description. * diff --git a/src/PhpPresentation/Shape/Drawing/Gd.php b/src/PhpPresentation/Shape/Drawing/Gd.php index 690966608..16fa6fe16 100644 --- a/src/PhpPresentation/Shape/Drawing/Gd.php +++ b/src/PhpPresentation/Shape/Drawing/Gd.php @@ -93,8 +93,8 @@ public function setImageResource($value = null) if (null !== $this->imageResource) { // Get width/height - $this->width = (int)@imagesx($this->imageResource); - $this->height = (int)@imagesy($this->imageResource); + $this->width = imagesx($this->imageResource); + $this->height = imagesy($this->imageResource); } return $this; diff --git a/src/PhpPresentation/Shape/Group.php b/src/PhpPresentation/Shape/Group.php index 4945f1561..17a424297 100644 --- a/src/PhpPresentation/Shape/Group.php +++ b/src/PhpPresentation/Shape/Group.php @@ -23,15 +23,11 @@ use PhpOffice\PhpPresentation\AbstractShape; use PhpOffice\PhpPresentation\GeometryCalculator; use PhpOffice\PhpPresentation\ShapeContainerInterface; +use PhpOffice\PhpPresentation\Traits\ShapeCollection; class Group extends AbstractShape implements ShapeContainerInterface { - /** - * Collection of shapes. - * - * @var array|ArrayObject - */ - private $shapeCollection; + use ShapeCollection; /** * Extent X. @@ -50,29 +46,6 @@ class Group extends AbstractShape implements ShapeContainerInterface public function __construct() { parent::__construct(); - - // Shape collection - $this->shapeCollection = new ArrayObject(); - } - - /** - * Get collection of shapes. - * - * @return array|ArrayObject - */ - public function getShapeCollection() - { - return $this->shapeCollection; - } - - /** - * Add shape to slide. - */ - public function addShape(AbstractShape $shape): AbstractShape - { - $shape->setContainer($this); - - return $shape; } /** diff --git a/src/PhpPresentation/Shape/RichText.php b/src/PhpPresentation/Shape/RichText.php index 86f75c924..90ada9913 100644 --- a/src/PhpPresentation/Shape/RichText.php +++ b/src/PhpPresentation/Shape/RichText.php @@ -45,20 +45,20 @@ class RichText extends AbstractShape implements ComparableInterface public const OVERFLOW_OVERFLOW = 'overflow'; /** Vertical alignment */ - const VALIGN_TOP = 't'; - const VALIGN_MIDDLE = 'ctr'; - const VALIGN_BOTTOM = 'b'; + public const VALIGN_TOP = 't'; + public const VALIGN_MIDDLE = 'ctr'; + public const VALIGN_BOTTOM = 'b'; /** Vertical alignment center */ - const VALIGN_CENTER = 1; - const VALIGN_NOTCENTER = 0; + public const VALIGN_CENTER = 1; + public const VALIGN_NOTCENTER = 0; /** * Rich text paragraphs. * * @var array */ - private $richTextParagraphs; + private $richTextParagraphs = []; /** * Active paragraph. @@ -184,6 +184,7 @@ class RichText extends AbstractShape implements ComparableInterface * @var string */ private $verticalAlign = self::VALIGN_TOP; + /** * Define vertical text center position into shape (center,not center) * @var int @@ -212,10 +213,9 @@ public function __clone() // Call perent clonage for heritage parent::__clone(); // Clone each paragraph - if (isset($this->richTextParagraphs)) { - foreach ($this->richTextParagraphs as &$paragraph) { + foreach ($this->richTextParagraphs as &$paragraph) { $paragraph = clone $paragraph; - }} + } } /** @@ -510,52 +510,53 @@ public function setVertical(bool $value = false): self /** * Define the vertical alignment * - * @param string|null $value top,center,bottom - * @return $this - * @see self::VALIGN_TOP, self::VALIGN_MIDLE, self::VALIGN_BOTTOM + * @param string $value top,center,bottom */ - public function setVerticalAlignment(?string $value) + public function setVerticalAlignment(string $value): self { - if (isset($value)) { + if (!in_array( + $value, + [self::VALIGN_TOP, self::VALIGN_MIDLE, self::VALIGN_BOTTOM] + )) { + throw new NotAllowedValueException($pValue, [self::VALIGN_TOP, self::VALIGN_MIDLE, self::VALIGN_BOTTOM]); + } + $this->verticalAlign = $value; - } else { - $this->verticalAlign = self::VALIGN_TOP; - } - return $this; + + return $this; } /** * Get the vertical alignment - * - * @return string - * @see self::VALIGN_TOP, self::VALIGN_MIDLE, self::VALIGN_BOTTOM */ - public function getVerticalAlignment():string + public function getVerticalAlignment(): string { - return $this->verticalAlign; + return $this->verticalAlign; } /** * Define the vertical alignment if centered or not - * @param int|null $value 1=center 0=not center - * @return $this + * @param int $value 1=center 0=not * @see self::VALIGN_CENTER, self::VALIGN_NOTCENTER */ - public function setVerticalAlignCenter(?int $value) + public function setVerticalAlignCenter(int $value): self { - if (isset($value)) { + if (!in_array( + $value, + [self::VALIGN_CENTER, self::VALIGN_NOTCENTER] + )) { + throw new NotAllowedValueException($pValue, [self::VALIGN_CENTER, self::VALIGN_NOTCENTER]); + } + $this->verticalAlignCenter = $value; - } else { - $this->verticalAlignCenter = self::VALIGN_NOTCENTER; - } + return $this; } /** * Get the vertical alignment center - * @return int */ - public function getVerticalAlignCenter():int + public function getVerticalAlignCenter(): int { return $this->verticalAlignCenter; } diff --git a/src/PhpPresentation/Shape/RichText/Paragraph.php b/src/PhpPresentation/Shape/RichText/Paragraph.php index 95c9004ce..15e2cf2f0 100644 --- a/src/PhpPresentation/Shape/RichText/Paragraph.php +++ b/src/PhpPresentation/Shape/RichText/Paragraph.php @@ -65,12 +65,6 @@ class Paragraph implements ComparableInterface */ private $lineSpacing = 100; - /** - * List of effect apply to paragraph - * @var array \PhpOffice\PhpPresentation\Style\Effect[] - */ - protected ?array $effectCollection = null; - /** * Hash index * @@ -103,7 +97,6 @@ public function __construct() $this->alignment = new Alignment(); $this->font = new Font(); $this->bulletStyle = new Bullet(); - $this->effectCollection = null; } /** @@ -111,16 +104,10 @@ public function __construct() */ public function __clone() { - // Clone each text - if (isset($this->richTextElements)) { - foreach ($this->richTextElements as &$txtElt) { - $txtElt = clone $txtElt; - }} - // Clone each effect - if (isset($this->effectCollection)) { - foreach ($this->effectCollection as &$effect) { - $effect = clone $effect; - }} + // Clone each text + foreach ($this->richTextElements as &$rtElement) { + $rtElement = clone $rtElement; + } } /** @@ -282,46 +269,6 @@ public function setRichTextElements(array $pElements = []): self return $this; } - /** - * Add an effect to the shpae - * - * @param \PhpOffice\PhpPresentation\Style\Effect $effect - * @return $this - */ - public function addEffect(Shape\Effect $effect) - { - if (!isset($this->effectCollection)) { - $this->effectCollection = array(); - } - $this->effectCollection[] = $effect; - return $this; - } - - /** - * Get the effect collection - * - * @return array \PhpOffice\PhpPresentation\Style\Effect[] - */ - public function getEffectCollection():?array - { - return $this->effectCollection; - } - - /** - * Set the effect collection - * - * @param array \PhpOffice\PhpPresentation\Style\Effect $effectCollection - * @return $this - */ - public function setEffectCollection(array $effectCollection) - { - if ( isset($effectCollection) - && is_array($effectCollection)) { - $this->effectCollection = $effectCollection; - } - return $this; - } - /** * Get hash code * diff --git a/src/PhpPresentation/Shape/RichText/Run.php b/src/PhpPresentation/Shape/RichText/Run.php index e4528acb6..a9f99fe3e 100644 --- a/src/PhpPresentation/Shape/RichText/Run.php +++ b/src/PhpPresentation/Shape/RichText/Run.php @@ -29,27 +29,18 @@ class Run extends TextElement implements TextElementInterface /** * Font. * - * @var \PhpOffice\PhpPresentation\Style\Font + * @var Font */ private $font; /** - * List of effect apply to paragraph - * @var array \PhpOffice\PhpPresentation\Style\Effect[] - */ - protected ?array $effectCollection = null; - - /** - * Create a new \PhpOffice\PhpPresentation\Shape\RichText\Run instance - * * @param string $pText Text */ public function __construct($pText = '') { - // Initialise variables + // Initialize variables $this->setText($pText); $this->font = new Font(); - $this->effectCollection = null; } /** @@ -63,9 +54,7 @@ public function getFont(): Font /** * Set font. * - * @param null|Font $pFont Font - * - * @return \PhpOffice\PhpPresentation\Shape\RichText\TextElementInterface + * @return self */ public function setFont(?Font $pFont = null) { @@ -75,49 +64,7 @@ public function setFont(?Font $pFont = null) } /** - * Add an effect to the shpae - * - * @param \PhpOffice\PhpPresentation\Style\Effect $effect - * @return $this - */ - public function addEffect(Shape\Effect $effect) - { - if (!isset($this->effectCollection)) { - $this->effectCollection = array(); - } - $this->effectCollection[] = $effect; - return $this; - } - - /** - * Get the effect collection - * - * @return array \PhpOffice\PhpPresentation\Style\Effect[] - */ - public function getEffectCollection():?array - { - return $this->effectCollection; - } - - /** - * Set the effect collection - * - * @param array \PhpOffice\PhpPresentation\Style\Effect $effectCollection - * @return $this - */ - public function setEffectCollection(array $effectCollection) - { - if ( isset($effectCollection) - && is_array($effectCollection)) { - $this->effectCollection = $effectCollection; - } - return $this; - } - - /** - * Get hash code - * - * @return string Hash code + * Get hash code. */ public function getHashCode(): string { diff --git a/src/PhpPresentation/Slide.php b/src/PhpPresentation/Slide.php index 150e14426..05876e713 100644 --- a/src/PhpPresentation/Slide.php +++ b/src/PhpPresentation/Slide.php @@ -74,8 +74,6 @@ public function __construct(?PhpPresentation $pParent = null) { // Set parent $this->parent = $pParent; - // Shape collection - $this->shapeCollection = new ArrayObject(); // Set identifier $this->identifier = md5(mt_rand(0, mt_getrandmax()) . time()); // Set Slide Layout @@ -139,7 +137,6 @@ public function __clone() $this->parent = clone $this->parent; // Shape collection if (isset($this->shapeCollection)) { - $this->shapeCollection = clone $this->shapeCollection; foreach ($this->shapeCollection as &$shape) { $shape = clone $shape; } diff --git a/src/PhpPresentation/Slide/AbstractSlide.php b/src/PhpPresentation/Slide/AbstractSlide.php index d67d51b16..e8a6398e1 100644 --- a/src/PhpPresentation/Slide/AbstractSlide.php +++ b/src/PhpPresentation/Slide/AbstractSlide.php @@ -30,10 +30,13 @@ use PhpOffice\PhpPresentation\Shape\Line; use PhpOffice\PhpPresentation\Shape\RichText; use PhpOffice\PhpPresentation\Shape\Table; +use PhpOffice\PhpPresentation\Traits\ShapeCollection; use PhpOffice\PhpPresentation\ShapeContainerInterface; abstract class AbstractSlide implements ComparableInterface, ShapeContainerInterface { + use ShapeCollection; + /** * @var string */ @@ -44,13 +47,6 @@ abstract class AbstractSlide implements ComparableInterface, ShapeContainerInter */ protected $slideTransition; - /** - * Collection of shapes. - * - * @var array|ArrayObject - */ - protected $shapeCollection = []; - /** * Extent Y. * @@ -107,56 +103,6 @@ abstract class AbstractSlide implements ComparableInterface, ShapeContainerInter */ protected $background; - /** - * Get collection of shapes. - * - * @return array|ArrayObject - */ - public function getShapeCollection() - { - return $this->shapeCollection; - } - - /** - * Search into collection of shapes for a name (eventually filtered by type ex: RichText) - * - * @param string $name The name to find into the shape collection - * @param PhpOffice\PhpPresentation\Shape\RichText | PhpOffice\PhpPresentation\Shape\... $type Type of the class - * @return \ArrayObject|\PhpOffice\PhpPresentation\AbstractShape[] - */ - public function searchShapeByName(string $name, ?string $type=null) - { - if (isset($this->shapeCollection)) { - foreach ($this->shapeCollection as $shape) { - if ($shape->getName() == $name) { - if (!isset($type) || get_class($shape) == $type) { - return $shape; - }}}} - return null; - } - - /** - * Get collection of shapes - * - * @return AbstractSlide - */ - public function setShapeCollection($shapeCollection = []) - { - $this->shapeCollection = $shapeCollection; - - return $this; - } - - /** - * Add shape to slide. - */ - public function addShape(AbstractShape $shape): AbstractShape - { - $shape->setContainer($this); - - return $shape; - } - /** * Get X Offset. */ diff --git a/src/PhpPresentation/Slide/Animation.php b/src/PhpPresentation/Slide/Animation.php index f5215ac2a..ac41c7056 100644 --- a/src/PhpPresentation/Slide/Animation.php +++ b/src/PhpPresentation/Slide/Animation.php @@ -20,41 +20,9 @@ namespace PhpOffice\PhpPresentation\Slide; use PhpOffice\PhpPresentation\AbstractShape; +use PhpOffice\PhpPresentation\Traits\ShapeCollection; class Animation { - /** - * @var array - */ - protected $shapeCollection = []; - - /** - * @return Animation - */ - public function addShape(AbstractShape $shape) - { - $this->shapeCollection[] = $shape; - - return $this; - } - - /** - * @return array - */ - public function getShapeCollection(): array - { - return $this->shapeCollection; - } - - /** - * @param array $array - * - * @return Animation - */ - public function setShapeCollection(array $array = []) - { - $this->shapeCollection = $array; - - return $this; - } + use ShapeCollection; } diff --git a/src/PhpPresentation/Slide/Note.php b/src/PhpPresentation/Slide/Note.php index d60542813..219d77ba8 100644 --- a/src/PhpPresentation/Slide/Note.php +++ b/src/PhpPresentation/Slide/Note.php @@ -26,9 +26,12 @@ use PhpOffice\PhpPresentation\Shape\RichText; use PhpOffice\PhpPresentation\ShapeContainerInterface; use PhpOffice\PhpPresentation\Slide; +use PhpOffice\PhpPresentation\Traits\ShapeCollection; class Note implements ComparableInterface, ShapeContainerInterface { + use ShapeCollection; + /** * Parent slide. * @@ -36,13 +39,6 @@ class Note implements ComparableInterface, ShapeContainerInterface */ private $parent; - /** - * Collection of shapes. - * - * @var array|ArrayObject - */ - private $shapeCollection; - /** * Note identifier. * @@ -93,33 +89,10 @@ public function __construct(?Slide $pParent = null) // Set parent $this->parent = $pParent; - // Shape collection - $this->shapeCollection = new ArrayObject(); - // Set identifier $this->identifier = md5(mt_rand(0, 9999) . time()); } - /** - * Get collection of shapes. - * - * @return array|ArrayObject - */ - public function getShapeCollection() - { - return $this->shapeCollection; - } - - /** - * Add shape to slide. - */ - public function addShape(AbstractShape $shape): AbstractShape - { - $shape->setContainer($this); - - return $shape; - } - /** * Create rich text shape. */ diff --git a/src/PhpPresentation/Slide/SlideLayout.php b/src/PhpPresentation/Slide/SlideLayout.php index 6393ca7e2..b5c034a97 100644 --- a/src/PhpPresentation/Slide/SlideLayout.php +++ b/src/PhpPresentation/Slide/SlideLayout.php @@ -73,8 +73,6 @@ public function __construct(SlideMaster $pSlideMaster) { // Set parent $this->slideMaster = $pSlideMaster; - // Shape collection - $this->shapeCollection = new ArrayObject(); // Set identifier $this->identifier = md5(mt_rand(0, 9999) . time()); // Set a basic colorMap diff --git a/src/PhpPresentation/Slide/SlideMaster.php b/src/PhpPresentation/Slide/SlideMaster.php index 9d877d3f2..8957e6543 100644 --- a/src/PhpPresentation/Slide/SlideMaster.php +++ b/src/PhpPresentation/Slide/SlideMaster.php @@ -80,8 +80,6 @@ public function __construct(?PhpPresentation $pParent = null) { // Set parent $this->parent = $pParent; - // Shape collection - $this->shapeCollection = new ArrayObject(); // Set identifier $this->identifier = md5(mt_rand(0, 9999) . time()); // Set a basic colorMap diff --git a/src/PhpPresentation/Style/Effect.php b/src/PhpPresentation/Style/Effect.php deleted file mode 100644 index 5c25ca4f4..000000000 --- a/src/PhpPresentation/Style/Effect.php +++ /dev/null @@ -1,310 +0,0 @@ -effectType = $type; - $this->blurRadius = 6; - $this->distance = 2; - $this->direction = 0; - $this->alignment = self::SHADOW_BOTTOM_RIGHT; - $this->color = new Color(Color::COLOR_BLACK); - $this->alpha = 50; - } - - /** - * Define the type effect - * - * @param string $type - * @return $this - * @see self::EFFECT_SHADOW_INNER, self::EFFECT_SHADOW_OUTER, self::EFFECT_REFLECTION - */ - public function setEffectType(string $type) - { - $this->effectType = $type; - return $this; - } - - /** - * Get the effect type - * - * @return string - */ - public function getEffectType():string - { - return $this->effectType; - } - - /** - * Set the direction - * - * @param int $dir - * @return $this - */ - public function setDirection(?int $dir) - { - if (!isset($dir)) $dir = 0; - $this->direction = (int)$dir; - return $this; - } - - /** - * Get the direction - * - * @return int - */ - public function getDirection():int - { - return $this->direction; - } - - /** - * Set the blur radius - * - * @param int $radius - * @return $this - */ - public function setBlurRadius(?int $radius) - { - if (!isset($radius)) $radius = 6; - $this->blurRadius = $radius; - return $this; - } - - /** - * Get the blur radius - * - * @return int - */ - public function getBlurRadius():int - { - return $this->blurRadius; - } - - /** - * Get Shadow distance - * - * @return int - */ - public function getDistance():int - { - return $this->distance; - } - - /** - * Set Shadow distance - * - * @param int $distance - * @return $this - */ - public function setDistance(int $distance = 2) - { - $this->distance = $distance; - - return $this; - } - - /** - * Set the effect alignment - * - * @param string $align - * @return $this - */ - public function setAlignment(?string $align) - { - if (!isset($align)) $align = self::SHADOW_BOTTOM_RIGHT; - $this->align = $align; - return $this; - } - - /** - * Get the effect alignment - * - * @return string - */ - public function getAlignment():string - { - return $this->align; - } - - /** - * Set Color - * - * @param \PhpOffice\PhpPresentation\Style\Color $color - * @return $this - */ - public function setColor(Color $color = null) - { - $this->color = $color; - - return $this; - } - - /** - * Get Color - * - * @return \PhpOffice\PhpPresentation\Style\Color - */ - public function getColor() - { - return $this->color; - } - - /** - * Set Alpha - * - * @param int $alpha - * @return $this - */ - public function setAlpha(?int $alpha) - { - if (!isset($alpha)) $alpha = 0; - $this->alpha = $alpha; - - return $this; - } - - /** - * Get Alpha - * - * @return int - */ - public function getAlpha():int - { - return $this->alpha; - } - - /** - * Get hash code - * - * @return string Hash code - */ - public function getHashCode() - { - return md5($this->effectType . $this->blurRadius . $this->distance . $this->direction . $this->alignment . $this->color->getHashCode() . $this->alpha . __CLASS__); - } - - /** - * Get hash index - * - * Note that this index may vary during script execution! Only reliable moment is - * while doing a write of a workbook and when changes are not allowed. - * - * @return string Hash index - */ - public function getHashIndex() - { - return $this->hashIndex; - } - - /** - * Set hash index - * - * Note that this index may vary during script execution! Only reliable moment is - * while doing a write of a workbook and when changes are not allowed. - * - * @param string $value Hash index - */ - public function setHashIndex($value) - { - $this->hashIndex = $value; - } - -} diff --git a/src/PhpPresentation/Style/Font.php b/src/PhpPresentation/Style/Font.php index 474d3e0e3..8c141525d 100644 --- a/src/PhpPresentation/Style/Font.php +++ b/src/PhpPresentation/Style/Font.php @@ -20,6 +20,7 @@ namespace PhpOffice\PhpPresentation\Style; use PhpOffice\PhpPresentation\ComparableInterface; +use PhpOffice\PhpPresentation\Exception\InvalidParameterException; use PhpOffice\PhpPresentation\Exception\NotAllowedValueException; /** @@ -27,6 +28,24 @@ */ class Font implements ComparableInterface { + // Capitalization type + public const CAPITALIZATION_NONE = 'none'; + public const CAPITALIZATION_SMALL = 'small'; + public const CAPITALIZATION_ALL = 'all'; + + // Charset type + public const CHARSET_DEFAULT = 0x01; + + // Format type + public const FORMAT_LATIN = 'latin'; + public const FORMAT_EAST_ASIAN = 'ea'; + public const FORMAT_COMPLEX_SCRIPT = 'cs'; + + // Strike type + public const STRIKE_NONE = 'noStrike'; + public const STRIKE_SINGLE = 'sngStrike'; + public const STRIKE_DOUBLE = 'dblStrike'; + // Underline types public const UNDERLINE_NONE = 'none'; public const UNDERLINE_DASH = 'dash'; @@ -46,23 +65,10 @@ class Font implements ComparableInterface public const UNDERLINE_WAVYDOUBLE = 'wavyDbl'; public const UNDERLINE_WAVYHEAVY = 'wavyHeavy'; public const UNDERLINE_WORDS = 'words'; - - /* Strike types */ - public const STRIKE_NONE = 'noStrike'; - public const STRIKE_SINGLE = 'sngStrike'; - public const STRIKE_DOUBLE = 'dblStrike'; - - public const FORMAT_LATIN = 'latin'; - public const FORMAT_EAST_ASIAN = 'ea'; - public const FORMAT_COMPLEX_SCRIPT = 'cs'; - - public const CAPITALIZATION_NONE = 'none'; - public const CAPITALIZATION_SMALL = 'small'; - public const CAPITALIZATION_ALL = 'all'; /* Script sub and super values */ - const SCRIPT_SUPER = 30000; - const SCRIPT_SUB = -25000; + public const BASELINE_SUPERSCRIPT = 300000; + public const BASELINE_SUBSCRIPT = -250000; /** * Name. @@ -72,23 +78,25 @@ class Font implements ComparableInterface private $name = 'Calibri'; /** - * panose + * Panose * * @var string */ - private $panose; + private $panose = ''; + /** - * pitchFamily + * Pitch Family * - * @var string + * @var int */ - private $pitchFamily; + private $pitchFamily = 0; + /** - * charset + * Charset * - * @var string + * @var int */ - private $charset; + private $charset = self::CHARSET_DEFAULT; /** * Font Size @@ -112,18 +120,11 @@ class Font implements ComparableInterface private $italic = false; /** - * Superscript. + * Baseline. * - * @var bool - */ - private $superScript = false; - - /** - * Subscript. - * - * @var bool + * @var int */ - private $subScript = false; + private $baseline = 0; /** * Capitalization. @@ -144,7 +145,7 @@ class Font implements ComparableInterface * * @var bool */ - private $strikethrough = false; + private $strikethrough = self::STRIKE_NONE; /** * Foreground color. @@ -177,9 +178,6 @@ class Font implements ComparableInterface public function __construct() { $this->color = new Color(Color::COLOR_BLACK); - $this->superScript = 0; - $this->subScript = 0; - $this->strikethrough = self::STRIKE_NONE; } /** @@ -203,51 +201,50 @@ public function setName(string $pValue = 'Calibri'): self } /** - * Get panose - * - * @return string + * Get panose. */ - public function getPanose() + public function getPanose(): string { return $this->panose; } /** - * Set panose - * - * @param string $pValue - * @return \PhpOffice\PhpPresentation\Style\Font + * Set panose. */ - public function setPanose($pValue) + public function setPanose(string $pValue): self { - if ($pValue == '') { - $pValue = ''; + if (mb_strlen($pValue) !== 10) { + throw new InvalidParameterException('pValue', $pValue, 'The length is not equals to 10'); + } + + $allowedChars = ['0', '1', '2', '3', '4', '5', '6' ,'7' ,'8' ,'9' ,'A' ,'B' ,'C' ,'D' ,'E' ,'F']; + foreach(mb_str_split($pValue) as $char) { + if (!in_array($char, $allowedChars)) { + throw new InvalidParameterException( + 'pValue', + $pValue, + sprintf('The character "%s" is not allowed', $char) + ); + } } + $this->panose = $pValue; return $this; } /** - * Get pitchFamily - * - * @return string + * Get pitchFamily. */ - public function getPitchFamily() + public function getPitchFamily(): int { return $this->pitchFamily; } /** - * Set pitchFamily - * - * @param string $pValue - * @return \PhpOffice\PhpPresentation\Style\Font + * Set pitchFamily. */ - public function setPitchFamily($pValue) + public function setPitchFamily(int $pValue): self { - if ($pValue == '') { - $pValue = ''; - } $this->pitchFamily = $pValue; return $this; @@ -255,24 +252,18 @@ public function setPitchFamily($pValue) /** * Get charset * - * @return string + * @return int */ - public function getCharset() + public function getCharset(): int { return $this->charset; } /** - * Set charset - * - * @param string $pValue - * @return \PhpOffice\PhpPresentation\Style\Font + * Set charset. */ - public function setCharset($pValue) + public function setCharset(int $pValue): self { - if ($pValue == '') { - $pValue = ''; - } $this->charset = $pValue; return $this; @@ -352,65 +343,57 @@ public function setItalic(bool $pValue = false): self } /** - * Get SuperScript. + * Set Baseline. */ - public function isSuperScript(): int + public function setBaseline(int $pValue): self { - return $this->superScript; + $this->baseline = $pValue; + + return $this; } /** - * Set SuperScript - * - * @param integer $pValue - * @return \PhpOffice\PhpPresentation\Style\Font + * Get Baseline. */ - public function setSuperScript($pValue = 0) + public function getBaseline(): int { - if ($pValue == '') { - $pValue = 0; - } - - $this->superScript = $pValue; + return $this->baseline; + } - // Set SubScript at false only if SuperScript is true - if ($pValue != 0) { - $this->subScript = 0; - } + /** + * Get SuperScript. + * @deprecated getBaseline() === self::BASELINE_SUPERSCRIPT + */ + public function isSuperScript(): bool + { + return $this->getBaseline() === self::BASELINE_SUPERSCRIPT; + } - return $this; + /** + * Set SuperScript + * @deprecated setBaseline(self::BASELINE_SUPERSCRIPT) + */ + public function setSuperScript(bool $pValue = false): self + { + return $this->setBaseline($pValue ? self::BASELINE_SUPERSCRIPT : ($this->getBaseline() == self::BASELINE_SUBSCRIPT ? $this->getBaseline() : 0)); } /** * Get SubScript - * - * @return integer + * @deprecated getBaseline() === self::BASELINE_SUBSCRIPT */ - public function isSubScript() + public function isSubScript(): bool { - return $this->subScript; + return $this->getBaseline() === self::BASELINE_SUBSCRIPT; } /** * Set SubScript - * - * @param integer $pValue - * @return \PhpOffice\PhpPresentation\Style\Font + * @deprecated setBaseline(self::BASELINE_SUBSCRIPT) */ - public function setSubScript($pValue = 0) + public function setSubScript(bool $pValue = false): self { - if ($pValue == '') { - $pValue = 0; - } - - $this->subScript = $pValue; - - // Set SuperScript at false only if SubScript is true - if ($pValue != 0) { - $this->superScript = 0; - } - - return $this; + return $this->setBaseline($pValue ? self::BASELINE_SUBSCRIPT : ($this->getBaseline() == self::BASELINE_SUPERSCRIPT ? $this->getBaseline() : 0)); } /** @@ -463,21 +446,39 @@ public function setUnderline(string $pValue = self::UNDERLINE_NONE): self /** * Get Strikethrough. + * @deprecated Use `getStrikethrough` */ public function isStrikethrough(): bool + { + return $this->strikethrough !== self::STRIKE_NONE; + } + + /** + * Get Strikethrough. + */ + public function getStrikethrough(): string { return $this->strikethrough; } /** * Set Strikethrough. + * + * @deprecated $pValue as boolean + * @param bool|string $pValue */ - public function setStrikethrough($pValue = self::STRIKE_NONE) + public function setStrikethrough($pValue = false) { - if ($pValue == '') { - $pValue = self::STRIKE_NONE; + if (is_bool($pValue)) { + $pValue = $pValue ? self::STRIKE_SINGLE : self::STRIKE_NONE; + } + if (in_array($pValue, [ + self::STRIKE_NONE, + self::STRIKE_SINGLE, + self::STRIKE_DOUBLE + ])) { + $this->strikethrough = $pValue; } - $this->strikethrough = $pValue; return $this; } @@ -536,8 +537,7 @@ public function getHashCode(): string . $this->size . ($this->bold ? 't' : 'f') . ($this->italic ? 't' : 'f') - . ($this->superScript ? 't' : 'f') - . ($this->subScript ? 't' : 'f') + . $this->baseline . $this->underline . ($this->strikethrough ? 't' : 'f') . $this->format diff --git a/src/PhpPresentation/Style/Shadow.php b/src/PhpPresentation/Style/Shadow.php index bdbae7e04..b3abccd6b 100644 --- a/src/PhpPresentation/Style/Shadow.php +++ b/src/PhpPresentation/Style/Shadow.php @@ -26,6 +26,10 @@ */ class Shadow implements ComparableInterface { + public const TYPE_SHADOW_INNER = 'innerShdw'; + public const TYPE_SHADOW_OUTER = 'outerShdw'; + public const TYPE_REFLECTION = 'reflection'; + // Shadow alignment public const SHADOW_BOTTOM = 'b'; public const SHADOW_BOTTOM_LEFT = 'bl'; @@ -81,6 +85,11 @@ class Shadow implements ComparableInterface */ private $alpha = 50; + /** + * @var string + */ + private $type = self::TYPE_SHADOW_OUTER; + /** * Hash index. * @@ -224,6 +233,31 @@ public function setAlpha(int $pValue = 0): self return $this; } + /** + * Get Type. + */ + public function getType(): string + { + return $this->type; + } + + /** + * Set Type. + */ + public function setType(string $pValue = self::TYPE_SHADOW_OUTER): self + { + if (!in_array( + $pValue, + [self::TYPE_REFLECTION, self::TYPE_SHADOW_INNER, self::TYPE_SHADOW_OUTER] + )) { + throw new NotAllowedValueException($pValue, [self::TYPE_REFLECTION, self::TYPE_SHADOW_INNER, self::TYPE_SHADOW_OUTER]); + } + + $this->type = $pValue; + + return $this; + } + /** * Get hash code. * @@ -231,7 +265,7 @@ public function setAlpha(int $pValue = 0): self */ public function getHashCode(): string { - return md5(($this->visible ? 't' : 'f') . $this->blurRadius . $this->distance . $this->direction . $this->alignment . $this->color->getHashCode() . $this->alpha . __CLASS__); + return md5(($this->visible ? 't' : 'f') . $this->blurRadius . $this->distance . $this->direction . $this->alignment . $this->type . $this->color->getHashCode() . $this->alpha . __CLASS__); } /** diff --git a/src/PhpPresentation/Traits/ShapeCollection.php b/src/PhpPresentation/Traits/ShapeCollection.php new file mode 100644 index 000000000..e188d4f86 --- /dev/null +++ b/src/PhpPresentation/Traits/ShapeCollection.php @@ -0,0 +1,86 @@ + + */ + protected $shapeCollection = []; + + /** + * Get collection of shapes. + * + * @return array + */ + public function getShapeCollection(): array + { + return $this->shapeCollection; + } + + /** + * Search into collection of shapes for a name or/and a type. + */ + public function searchShapes(?string $name = null, ?string $type = null): array + { + $found = []; + foreach ($this->getShapeCollection() as $shape) { + if ($name && $shape->getName() !== $name) { + continue; + } + if ($type && get_class($shape) !== $type) { + continue; + } + + $found[] = $shape; + } + + return $found; + } + + /** + * Get collection of shapes. + */ + public function setShapeCollection(array $shapeCollection = []): self + { + $this->shapeCollection = $shapeCollection; + + return $this; + } + + public function addShape(AbstractShape $shape): self + { + $this->shapeCollection[] = $shape; + + return $this; + } + + public function unsetShape(int $key): self + { + unset($this->shapeCollection[$key]); + + return $this; + } +} diff --git a/src/PhpPresentation/Writer/AbstractWriter.php b/src/PhpPresentation/Writer/AbstractWriter.php index 3d935c417..d389f6862 100644 --- a/src/PhpPresentation/Writer/AbstractWriter.php +++ b/src/PhpPresentation/Writer/AbstractWriter.php @@ -116,7 +116,7 @@ protected function allDrawings(): array // Loop through PhpPresentation foreach (array_merge($this->getPhpPresentation()->getAllSlides(), $aSlideMasters, $aSlideLayouts) as $oSlide) { - $arrayReturn = $this->iterateCollection($oSlide->getShapeCollection()->getIterator()); + $arrayReturn = $this->iterateCollection($oSlide->getShapeCollection()); $aDrawings = array_merge($aDrawings, $arrayReturn); } @@ -124,28 +124,23 @@ protected function allDrawings(): array } /** - * @param ArrayIterator $oIterator + * @param array $collection * * @return array */ - private function iterateCollection(ArrayIterator $oIterator): array + private function iterateCollection(array $collection): array { $arrayReturn = []; - if ($oIterator->count() <= 0) { - return $arrayReturn; - } - while ($oIterator->valid()) { - $oShape = $oIterator->current(); + foreach($collection as $oShape) { if ($oShape instanceof AbstractDrawingAdapter) { $arrayReturn[] = $oShape; } elseif ($oShape instanceof Chart) { $arrayReturn[] = $oShape; } elseif ($oShape instanceof Group) { - $arrayGroup = $this->iterateCollection($oShape->getShapeCollection()->getIterator()); + $arrayGroup = $this->iterateCollection($oShape->getShapeCollection()); $arrayReturn = array_merge($arrayReturn, $arrayGroup); } - $oIterator->next(); } return $arrayReturn; diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index 79ea0c22a..1e6ffcfe5 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php @@ -49,6 +49,7 @@ use PhpOffice\PhpPresentation\Style\Border; use PhpOffice\PhpPresentation\Style\Bullet; use PhpOffice\PhpPresentation\Style\Color; +use PhpOffice\PhpPresentation\Style\Font; use PhpOffice\PhpPresentation\Style\Shadow; abstract class AbstractSlide extends AbstractDecoratorWriter @@ -58,60 +59,56 @@ abstract class AbstractSlide extends AbstractDecoratorWriter */ protected function writeDrawingRelations(AbstractSlideAlias $pSlideMaster, XMLWriter $objWriter, int $relId) { - if ($pSlideMaster->getShapeCollection()->count() > 0) { + if (count($pSlideMaster->getShapeCollection()) > 0) { // Loop trough images and write relationships - $iterator = $pSlideMaster->getShapeCollection()->getIterator(); - while ($iterator->valid()) { - if ($iterator->current() instanceof ShapeDrawingFile || $iterator->current() instanceof ShapeDrawingGd) { + foreach($pSlideMaster->getShapeCollection() as $shape) { + if ($shape instanceof ShapeDrawingFile || $shape instanceof ShapeDrawingGd) { // Write relationship for image drawing $this->writeRelationship( $objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', - '../media/' . str_replace(' ', '_', $iterator->current()->getIndexedFilename()) + '../media/' . str_replace(' ', '_', $shape->getIndexedFilename()) ); - $iterator->current()->relationId = 'rId' . $relId; + $shape->relationId = 'rId' . $relId; ++$relId; - } elseif ($iterator->current() instanceof ShapeChart) { + } elseif ($shape instanceof ShapeChart) { // Write relationship for chart drawing $this->writeRelationship( $objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', - '../charts/' . $iterator->current()->getIndexedFilename() + '../charts/' . $shape->getIndexedFilename() ); - $iterator->current()->relationId = 'rId' . $relId; + $shape->relationId = 'rId' . $relId; ++$relId; - } elseif ($iterator->current() instanceof Group) { - $iterator2 = $iterator->current()->getShapeCollection()->getIterator(); - while ($iterator2->valid()) { - if ($iterator2->current() instanceof ShapeDrawingFile || - $iterator2->current() instanceof ShapeDrawingGd + } elseif ($shape instanceof Group) { + foreach($shape->getShapeCollection() as $subShape) { + if ($subShape instanceof ShapeDrawingFile || + $subShape instanceof ShapeDrawingGd ) { // Write relationship for image drawing $this->writeRelationship( $objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', - '../media/' . str_replace(' ', '_', $iterator2->current()->getIndexedFilename()) + '../media/' . str_replace(' ', '_', $subShape->getIndexedFilename()) ); - $iterator2->current()->relationId = 'rId' . $relId; + $subShape->relationId = 'rId' . $relId; ++$relId; - } elseif ($iterator2->current() instanceof ShapeChart) { + } elseif ($subShape instanceof ShapeChart) { // Write relationship for chart drawing $this->writeRelationship( $objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', - '../charts/' . $iterator2->current()->getIndexedFilename() + '../charts/' . $subShape->getIndexedFilename() ); - $iterator2->current()->relationId = 'rId' . $relId; + $subShape->relationId = 'rId' . $relId; ++$relId; } - $iterator2->next(); } } - $iterator->next(); } } @@ -228,7 +225,7 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, int $sh $this->writeFill($objWriter, $shape->getFill()); $this->writeBorder($objWriter, $shape->getBorder(), ''); - $this->writeEffect($objWriter, $shape->getEffectCollection()); + $this->writeShadow($objWriter, $shape->getShadow()); // > p:sp\p:spPr $objWriter->endElement(); @@ -267,7 +264,7 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, int $sh $objWriter->writeAttribute('tIns', CommonDrawing::pixelsToEmu($shape->getInsetTop())); // Vertical alignment $objWriter->writeAttribute('anchor', $shape->getVerticalAlignment()); - $objWriter->writeAttribute('anchorCtr', (int)$shape->getVerticalAlignCenter()); + $objWriter->writeAttribute('anchorCtr', $shape->getVerticalAlignCenter()); if ($shape->getColumns() <> 1) { $objWriter->writeAttribute('numCol', $shape->getColumns()); $objWriter->writeAttribute('spcCol', CommonDrawing::pixelsToEmu($shape->getColumnSpacing())); @@ -655,7 +652,9 @@ protected function writeRunStyles(XMLWriter $objWriter, RichText\Run $element): $objWriter->writeAttributeIf($element->getFont()->isBold(), 'b', '1'); $objWriter->writeAttributeIf($element->getFont()->isItalic(), 'i', '1'); - $objWriter->writeAttributeIf($element->getFont()->isStrikethrough(), 'strike', $element->getFont()->isStrikethrough()); + + // Strikethrough + $objWriter->writeAttribute('strike', $element->getFont()->getStrikethrough()); // Size $objWriter->writeAttribute('sz', ($element->getFont()->getSize() * 100)); @@ -669,17 +668,16 @@ protected function writeRunStyles(XMLWriter $objWriter, RichText\Run $element): // Capitalization $objWriter->writeAttribute('cap', $element->getFont()->getCapitalization()); - // Superscript / subscript - $objWriter->writeAttributeIf($element->getFont()->isSuperScript() != 0, 'baseline', (int)$element->getFont()->isSuperScript()); - $objWriter->writeAttributeIf($element->getFont()->isSubScript() != 0, 'baseline', (int)$element->getFont()->isSubScript()); + // Baseline + $objWriter->writeAttributeIf($element->getFont()->getBaseline() !== 0, 'baseline', $element->getFont()->getBaseline()); // Color - a:solidFill $objWriter->startElement('a:solidFill'); $this->writeColor($objWriter, $element->getFont()->getColor()); $objWriter->endElement(); - // Write Effects - $this->writeEffect($objWriter, $element->getEffectCollection(), 'srgbClr'); + // Write Shadow + $this->writeShadow($objWriter, $shape->getShadow()); // Font // - a:latin @@ -687,12 +685,23 @@ protected function writeRunStyles(XMLWriter $objWriter, RichText\Run $element): // - a:cs $objWriter->startElement('a:' . $element->getFont()->getFormat()); $objWriter->writeAttribute('typeface', $element->getFont()->getName()); - if ($element->getFont()->getPanose()!="") - $objWriter->writeAttribute('panose', $element->getFont()->getPanose()); - if ($element->getFont()->getPitchFamily()!="") - $objWriter->writeAttribute('pitchFamily', $element->getFont()->getPitchFamily()); - if ($element->getFont()->getCharset()!="") - $objWriter->writeAttribute('charset', $element->getFont()->getCharset()); + if ($element->getFont()->getPanose() !== '') { + $panose = array_map(function(string $value) { + return '0' . $value; + }, str_split($element->getFont()->getPanose())); + + $objWriter->writeAttribute('panose', implode('', $panose)); + } + $objWriter->writeAttributeIf( + $element->getFont()->getPitchFamily() !== 0, + 'pitchFamily', + $element->getFont()->getPitchFamily() + ); + $objWriter->writeAttributeIf( + $element->getFont()->getCharset() !== Font::CHARSET_DEFAULT, + 'charset', + dechex($element->getFont()->getCharset()) + ); $objWriter->endElement(); // a:hlinkClick @@ -806,7 +815,7 @@ protected function writeShadow(XMLWriter $objWriter, Shadow $oShadow): void $objWriter->startElement('a:effectLst'); // a:outerShdw - $objWriter->startElement('a:outerShdw'); + $objWriter->startElement('a:' . $oShadow->getType()); $objWriter->writeAttribute('blurRad', CommonDrawing::pixelsToEmu($oShadow->getBlurRadius())); $objWriter->writeAttribute('dist', CommonDrawing::pixelsToEmu($oShadow->getDistance())); $objWriter->writeAttribute('dir', CommonDrawing::degreesToAngle((int) $oShadow->getDirection())); @@ -820,54 +829,6 @@ protected function writeShadow(XMLWriter $objWriter, Shadow $oShadow): void $objWriter->endElement(); } - /** - * Write Effect - * @param XMLWriter $objWriter - * @param array \PhpOffice\PhpPresentation\Style\Effect[] - * @param Shadow $oShadow - */ - protected function writeEffect(XMLWriter $objWriter, ?array $aEffect, ?string $tagClr=null) - { - // NO Effect => return - if (!isset($aEffect) && !is_array($aEffect)) { - return; - } - if (!isset($tagClr)) { - $tagClr = 'prstClr'; - } - - // a:effectLst - $objWriter->startElement('a:effectLst'); - // Write each effect - foreach($aEffect as $effect) { - // a: - if ( $effect->getEffectType() == 'outerShdw' - || $effect->getEffectType() == 'innerShdw') { -// @TODO || $effect->getEffectType() == 'reflection') { - - $objWriter->startElement('a:'.$effect->getEffectType()); - $objWriter->writeAttribute('blurRad', CommonDrawing::pixelsToEmu($effect->getBlurRadius())); - $objWriter->writeAttribute('dist', CommonDrawing::pixelsToEmu($effect->getDistance())); - $objWriter->writeAttribute('dir', CommonDrawing::degreesToAngle($effect->getDirection())); - $objWriter->writeAttribute('algn', $effect->getAlignment()); - $objWriter->writeAttribute('rotWithShape', '0'); - - // a:prstClr - $objWriter->startElement('a:'.$tagClr); - $objWriter->writeAttribute('val', $effect->getColor()->getRGB()); - // a:alpha - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $effect->getAlpha() * 1000); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->endElement(); - } - } - - $objWriter->endElement(); - } - /** * Write hyperlink * @@ -1500,7 +1461,7 @@ protected function writeShapePic(XMLWriter $objWriter, AbstractGraphic $shape, i $this->writeFill($objWriter, $shape->getFill()); $this->writeBorder($objWriter, $shape->getBorder(), ''); - $this->writeEffect($objWriter, $shape->getEffectCollection()); + $this->writeShadow($objWriter, $shape->getShadow()); $objWriter->endElement(); diff --git a/src/PhpPresentation/Writer/PowerPoint2007/ContentTypes.php b/src/PhpPresentation/Writer/PowerPoint2007/ContentTypes.php index 541e8c1d1..aa8ea2a9d 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/ContentTypes.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/ContentTypes.php @@ -85,7 +85,7 @@ public function render(): ZipInterface for ($i = 0; $i < $slideCount; ++$i) { $oSlide = $this->oPresentation->getSlide($i); $this->writeOverrideContentType($objWriter, '/ppt/slides/slide' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml'); - if ($oSlide->getNote()->getShapeCollection()->count() > 0) { + if (count($oSlide->getNote()->getShapeCollection()) > 0) { $this->writeOverrideContentType($objWriter, '/ppt/notesSlides/notesSlide' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml'); } foreach ($oSlide->getShapeCollection() as $oShape) { diff --git a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php index 6df85cde0..d21f6863a 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php @@ -70,18 +70,17 @@ public function render(): ZipInterface // cp:keywords $objWriter->writeElement('cp:keywords', $this->oPresentation->getDocumentProperties()->getKeywords()); + // cp:category + $objWriter->writeElement('cp:category', $this->oPresentation->getDocumentProperties()->getCategory()); + // cp:revision $objWriter->writeElement('cp:revision', $this->oPresentation->getDocumentProperties()->getRevision()); // cp:contentStatus - $objWriter->writeElement('cp:contentStatus', $this->oPresentation->getDocumentProperties()->getStatus()); - - // cp:category - $objWriter->writeElement('cp:category', $this->oPresentation->getDocumentProperties()->getCategory()); - if ($this->oPresentation->getPresentationProperties()->isMarkedAsFinal()) { - // cp:contentStatus = Final $objWriter->writeElement('cp:contentStatus', 'Final'); + } else { + $objWriter->writeElement('cp:contentStatus', $this->oPresentation->getDocumentProperties()->getStatus()); } $objWriter->endElement(); diff --git a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsThumbnail.php b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsThumbnail.php index 103309e5c..fde2f6f36 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsThumbnail.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsThumbnail.php @@ -20,31 +20,15 @@ namespace PhpOffice\PhpPresentation\Writer\PowerPoint2007; use PhpOffice\Common\Adapter\Zip\ZipInterface; +use PhpOffice\PhpPresentation\PresentationProperties; class DocPropsThumbnail extends AbstractDecoratorWriter { public function render(): ZipInterface { - $pathThumbnail = $this->getPresentation()->getPresentationProperties()->getThumbnailPath(); - $type = $this->getPresentation()->getPresentationProperties()->getThumbnailType(); - - // From local file - if ($pathThumbnail && $type == \PhpOffice\PhpPresentation\PresentationProperties::THUMBNAIL_FILE) { - $fileThumbnail = file_get_contents($pathThumbnail); - $gdImage = imagecreatefromstring($fileThumbnail); - if ($gdImage) { - ob_start(); - imagejpeg($gdImage); - $imageContents = ob_get_contents(); - ob_end_clean(); - imagedestroy($gdImage); - $this->getZip()->addFromString('docProps/thumbnail.jpeg', $imageContents); - } - } - - // From ZIP original file - if ($pathThumbnail && $type == \PhpOffice\PhpPresentation\PresentationProperties::THUMBNAIL_ZIP) { - $gdImage = imagecreatefromstring($this->getPresentation()->getPresentationProperties()->getThumbnail()); + $thumnbail = $this->getPresentation()->getPresentationProperties()->getThumbnail(); + if ($thumnbail) { + $gdImage = imagecreatefromstring($thumnbail); if ($gdImage) { ob_start(); imagejpeg($gdImage); diff --git a/src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php b/src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php index d2cd90410..c03d97621 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php @@ -447,11 +447,10 @@ protected function writeTitle(XMLWriter $objWriter, Title $subject): void $objWriter->writeAttribute('dirty', '0'); $objWriter->writeAttribute('b', ($subject->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($subject->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($subject->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $subject->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($subject->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $subject->getFont()->getUnderline()); - $objWriter->writeAttributeIf($subject->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($subject->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($subject->getFont()->getBaseline() !== 0, 'baseline', $subject->getFont()->getBaseline()); $objWriter->writeAttribute('cap', $subject->getFont()->getCapitalization()); // Font - a:solidFill @@ -609,11 +608,10 @@ protected function writeLegend(XMLWriter $objWriter, Legend $subject): void $objWriter->writeAttribute('b', ($subject->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($subject->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($subject->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $subject->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($subject->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $subject->getFont()->getUnderline()); - $objWriter->writeAttributeIf($subject->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($subject->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($subject->getFont()->getBaseline() !== 0, 'baseline', $subject->getFont()->getBaseline()); // Font - a:solidFill $objWriter->startElement('a:solidFill'); @@ -895,11 +893,10 @@ protected function writeTypeBar(XMLWriter $objWriter, Bar $subject, bool $includ $objWriter->startElement('a:defRPr'); $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $series->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); - $objWriter->writeAttributeIf($series->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($series->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($series->getFont()->getBaseline() !== 0, 'baseline', $series->getFont()->getBaseline()); // a:solidFill $objWriter->startElement('a:solidFill'); @@ -1102,11 +1099,10 @@ protected function writeTypeBar3D(XMLWriter $objWriter, Bar3D $subject, bool $in $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $series->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); - $objWriter->writeAttributeIf($series->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($series->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($series->getFont()->getBaseline() !== 0, 'baseline', $series->getFont()->getBaseline()); // Font - a:solidFill $objWriter->startElement('a:solidFill'); @@ -1311,11 +1307,10 @@ protected function writeTypeDoughnut(XMLWriter $objWriter, Doughnut $subject, bo $objWriter->startElement('a:defRPr'); $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $series->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); - $objWriter->writeAttributeIf($series->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($series->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($series->getFont()->getBaseline() !== 0, 'baseline', $series->getFont()->getBaseline()); // c:dLbls\c:txPr\a:p\a:pPr\a:defRPr\a:solidFill $objWriter->startElement('a:solidFill'); @@ -1454,11 +1449,10 @@ protected function writeTypePie(XMLWriter $objWriter, Pie $subject, bool $includ $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $series->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); - $objWriter->writeAttributeIf($series->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($series->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($series->getFont()->getBaseline() !== 0, 'baseline', $series->getFont()->getBaseline()); // Font - a:solidFill $objWriter->startElement('a:solidFill'); @@ -1618,11 +1612,10 @@ protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, bool $in $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $series->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); - $objWriter->writeAttributeIf($series->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($series->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($series->getFont()->getBaseline() !== 0, 'baseline', $series->getFont()->getBaseline()); // Font - a:solidFill $objWriter->startElement('a:solidFill'); @@ -1771,11 +1764,10 @@ protected function writeTypeLine(XMLWriter $objWriter, Line $subject, bool $incl $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $series->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); - $objWriter->writeAttributeIf($series->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($series->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($series->getFont()->getBaseline() !== 0, 'baseline', $series->getFont()->getBaseline()); // Font - a:solidFill $objWriter->startElement('a:solidFill'); @@ -1947,11 +1939,10 @@ protected function writeTypeRadar(XMLWriter $objWriter, Radar $subject, bool $in $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $series->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); - $objWriter->writeAttributeIf($series->getFont()->isSuperScript(), 'baseline', '30000'); - $objWriter->writeAttributeIf($series->getFont()->isSubScript(), 'baseline', '-25000'); + $objWriter->writeAttributeIf($series->getFont()->getBaseline() !== 0, 'baseline', $series->getFont()->getBaseline()); // Font - a:solidFill $objWriter->startElement('a:solidFill'); @@ -2113,11 +2104,10 @@ protected function writeTypeScatter(XMLWriter $objWriter, Scatter $subject, bool $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $series->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); - $objWriter->writeAttributeIf($series->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($series->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($series->getFont()->getBaseline() !== 0, 'baseline', $series->getFont()->getBaseline()); // Font - a:solidFill $objWriter->startElement('a:solidFill'); @@ -2392,11 +2382,10 @@ protected function writeAxis(XMLWriter $objWriter, Chart\Axis $oAxis, string $ty $objWriter->writeAttribute('b', ($oAxis->getFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($oAxis->getFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($oAxis->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $oAxis->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($oAxis->getFont()->getSize() * 100)); $objWriter->writeAttribute('u', $oAxis->getFont()->getUnderline()); - $objWriter->writeAttributeIf($oAxis->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($oAxis->getFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($oAxis->getFont()->getBaseline() !== 0, 'baseline', $oAxis->getFont()->getBaseline()); // Font - a:solidFill $objWriter->startElement('a:solidFill'); @@ -2496,11 +2485,10 @@ protected function writeAxis(XMLWriter $objWriter, Chart\Axis $oAxis, string $ty $objWriter->startElement('a:defRPr'); $objWriter->writeAttribute('b', ($oAxis->getTickLabelFont()->isBold() ? 'true' : 'false')); $objWriter->writeAttribute('i', ($oAxis->getTickLabelFont()->isItalic() ? 'true' : 'false')); - $objWriter->writeAttribute('strike', ($oAxis->getTickLabelFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('strike', $oAxis->getFont()->getStrikethrough()); $objWriter->writeAttribute('sz', ($oAxis->getTickLabelFont()->getSize() * 100)); $objWriter->writeAttribute('u', $oAxis->getTickLabelFont()->getUnderline()); - $objWriter->writeAttributeIf($oAxis->getTickLabelFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($oAxis->getTickLabelFont()->isSubScript(), 'baseline', '-250000'); + $objWriter->writeAttributeIf($oAxis->getTickLabelFont()->getBaseline() !== 0, 'baseline', $oAxis->getTickLabelFont()->getBaseline()); // Font - a:solidFill $objWriter->startElement('a:solidFill'); diff --git a/src/PhpPresentation/Writer/PowerPoint2007/PptSlides.php b/src/PhpPresentation/Writer/PowerPoint2007/PptSlides.php index 00da6cbf8..0e0140151 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/PptSlides.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/PptSlides.php @@ -49,7 +49,7 @@ public function render(): ZipInterface // Add note slide if ($oSlide->getNote() instanceof Note) { - if ($oSlide->getNote()->getShapeCollection()->count() > 0) { + if (count($oSlide->getNote()->getShapeCollection()) > 0) { $this->oZip->addFromString('ppt/notesSlides/notesSlide' . ($idx + 1) . '.xml', $this->writeNote($oSlide->getNote())); } } @@ -96,16 +96,14 @@ protected function writeSlideRelationships(Slide $pSlide): string ++$relId; // Write drawing relationships? - if ($pSlide->getShapeCollection()->count() > 0) { - $collections = [$pSlide->getShapeCollection()->getIterator()]; + if (count($pSlide->getShapeCollection()) > 0) { + $collections = [$pSlide->getShapeCollection()]; // Loop trough images and write relationships while (count($collections)) { - $iterator = array_shift($collections); - - while ($iterator->valid()) { - $currentShape = $iterator->current(); + $collection = array_shift($collections); + foreach($collection as $currentShape) { if ($currentShape instanceof Media) { // Write relationship for image drawing $currentShape->relationId = 'rId' . $relId; @@ -124,10 +122,8 @@ protected function writeSlideRelationships(Slide $pSlide): string $currentShape->relationId = 'rId' . $relId; ++$relId; } elseif ($currentShape instanceof ShapeContainerInterface) { - $collections[] = $currentShape->getShapeCollection()->getIterator(); + $collections[] = $currentShape->getShapeCollection(); } - - $iterator->next(); } } } @@ -141,14 +137,13 @@ protected function writeSlideRelationships(Slide $pSlide): string } // Write hyperlink relationships? - if ($pSlide->getShapeCollection()->count() > 0) { + if (count($pSlide->getShapeCollection()) > 0) { // Loop trough hyperlinks and write relationships - $iterator = $pSlide->getShapeCollection()->getIterator(); - while ($iterator->valid()) { + foreach($pSlide->getShapeCollection() as $shape) { // Hyperlink on shape - if ($iterator->current()->hasHyperlink()) { + if ($shape->hasHyperlink()) { // Write relationship for hyperlink - $hyperlink = $iterator->current()->getHyperlink(); + $hyperlink = $shape->getHyperlink(); $hyperlink->relationId = 'rId' . $relId; if (!$hyperlink->isInternal()) { @@ -161,8 +156,8 @@ protected function writeSlideRelationships(Slide $pSlide): string } // Hyperlink on rich text run - if ($iterator->current() instanceof RichText) { - foreach ($iterator->current()->getParagraphs() as $paragraph) { + if ($shape instanceof RichText) { + foreach ($shape->getParagraphs() as $paragraph) { foreach ($paragraph->getRichTextElements() as $element) { if ($element instanceof Run || $element instanceof TextElement) { if ($element->hasHyperlink()) { @@ -184,14 +179,14 @@ protected function writeSlideRelationships(Slide $pSlide): string } // Hyperlink in table - if ($iterator->current() instanceof ShapeTable) { + if ($shape instanceof ShapeTable) { // Rows - $countRows = count($iterator->current()->getRows()); + $countRows = count($shape->getRows()); for ($row = 0; $row < $countRows; ++$row) { // Cells in rows - $countCells = count($iterator->current()->getRow($row)->getCells()); + $countCells = count($shape->getRow($row)->getCells()); for ($cell = 0; $cell < $countCells; ++$cell) { - $currentCell = $iterator->current()->getRow($row)->getCell($cell); + $currentCell = $shape->getRow($row)->getCell($cell); // Paragraphs in cell foreach ($currentCell->getParagraphs() as $paragraph) { // RichText in paragraph @@ -218,13 +213,12 @@ protected function writeSlideRelationships(Slide $pSlide): string } } - if ($iterator->current() instanceof Group) { - $iterator2 = $pSlide->getShapeCollection()->getIterator(); - while ($iterator2->valid()) { + if ($shape instanceof Group) { + foreach($shape->getShapeCollection() as $subShape) { // Hyperlink on shape - if ($iterator2->current()->hasHyperlink()) { + if ($subShape->hasHyperlink()) { // Write relationship for hyperlink - $hyperlink = $iterator2->current()->getHyperlink(); + $hyperlink = $subShape->getHyperlink(); $hyperlink->relationId = 'rId' . $relId; if (!$hyperlink->isInternal()) { @@ -237,8 +231,8 @@ protected function writeSlideRelationships(Slide $pSlide): string } // Hyperlink on rich text run - if ($iterator2->current() instanceof RichText) { - foreach ($iterator2->current()->getParagraphs() as $paragraph) { + if ($subShape instanceof RichText) { + foreach ($subShape->getParagraphs() as $paragraph) { foreach ($paragraph->getRichTextElements() as $element) { if ($element instanceof Run || $element instanceof TextElement) { if ($element->hasHyperlink()) { @@ -260,14 +254,14 @@ protected function writeSlideRelationships(Slide $pSlide): string } // Hyperlink in table - if ($iterator2->current() instanceof ShapeTable) { + if ($subShape instanceof ShapeTable) { // Rows - $countRows = count($iterator2->current()->getRows()); + $countRows = count($subShape->getRows()); for ($row = 0; $row < $countRows; ++$row) { // Cells in rows - $countCells = count($iterator2->current()->getRow($row)->getCells()); + $countCells = count($subShape->getRow($row)->getCells()); for ($cell = 0; $cell < $countCells; ++$cell) { - $currentCell = $iterator2->current()->getRow($row)->getCell($cell); + $currentCell = $subShape->getRow($row)->getCell($cell); // Paragraphs in cell foreach ($currentCell->getParagraphs() as $paragraph) { // RichText in paragraph @@ -293,39 +287,30 @@ protected function writeSlideRelationships(Slide $pSlide): string } } } - - $iterator2->next(); } } - - $iterator->next(); } } // Write comment relationships - if ($pSlide->getShapeCollection()->count() > 0) { + if (count($pSlide->getShapeCollection()) > 0) { $hasSlideComment = false; // Loop trough images and write relationships - $iterator = $pSlide->getShapeCollection()->getIterator(); - while ($iterator->valid()) { - if ($iterator->current() instanceof Comment) { + foreach($pSlide->getShapeCollection() as $shape) { + if ($shape instanceof Comment) { $hasSlideComment = true; break; - } elseif ($iterator->current() instanceof Group) { - $iterator2 = $iterator->current()->getShapeCollection()->getIterator(); - while ($iterator2->valid()) { - if ($iterator2->current() instanceof Comment) { + } elseif ($shape instanceof Group) { + foreach($shape->getShapeCollection() as $subShape) { + if ($subShape instanceof Comment) { $hasSlideComment = true; break 2; } - $iterator2->next(); } } - - $iterator->next(); } if ($hasSlideComment) { @@ -334,7 +319,7 @@ protected function writeSlideRelationships(Slide $pSlide): string } } - if ($pSlide->getNote()->getShapeCollection()->count() > 0) { + if (count($pSlide->getNote()->getShapeCollection()) > 0) { $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide', '../notesSlides/notesSlide' . ($idxSlide + 1) . '.xml'); } diff --git a/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php b/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php index 804c175e2..7d652778c 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php @@ -63,29 +63,18 @@ protected function writeRelationships(): string $this->writeRelationship($objWriter, 4, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties', 'docProps/custom.xml'); $idxRelation = 5; - // Thumbnail - $path = $this->getPresentation()->getPresentationProperties()->getThumbnailPath(); - $type = $this->getPresentation()->getPresentationProperties()->getThumbnailType(); - // From local file - if ($path && $type == \PhpOffice\PhpPresentation\PresentationProperties::THUMBNAIL_FILE) { - $pathThumbnail = file_get_contents($path); - $gdImage = imagecreatefromstring($pathThumbnail); - if ($gdImage) { - imagedestroy($gdImage); - // Relationship docProps/thumbnail.jpeg - $this->writeRelationship($objWriter, $idxRelation, 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail', 'docProps/thumbnail.jpeg'); - } - } - // From ZIP original file - if ($path && $type == \PhpOffice\PhpPresentation\PresentationProperties::THUMBNAIL_ZIP) { - $gdImage = imagecreatefromstring($this->getPresentation()->getPresentationProperties()->getThumbnail()); + + // Relationship docProps/thumbnail.jpeg + $thumnbail = $this->getPresentation()->getPresentationProperties()->getThumbnail(); + if ($thumnbail) { + $gdImage = imagecreatefromstring($thumnbail); if ($gdImage) { imagedestroy($gdImage); // Relationship docProps/thumbnail.jpeg $this->writeRelationship($objWriter, $idxRelation, 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail', 'docProps/thumbnail.jpeg'); + // $idxRelation++; } } - // ++$idxRelation $objWriter->endElement(); diff --git a/src/PhpPresentation/Writer/Serialized.php b/src/PhpPresentation/Writer/Serialized.php index 72ac2790a..fc55fa6ff 100644 --- a/src/PhpPresentation/Writer/Serialized.php +++ b/src/PhpPresentation/Writer/Serialized.php @@ -66,12 +66,11 @@ public function save(string $pFilename): void // Add media $slideCount = $oPresentation->getSlideCount(); for ($i = 0; $i < $slideCount; ++$i) { - for ($j = 0; $j < $oPresentation->getSlide($i)->getShapeCollection()->count(); ++$j) { - if ($oPresentation->getSlide($i)->getShapeCollection()->offsetGet($j) instanceof AbstractDrawingAdapter) { - $imgTemp = $oPresentation->getSlide($i)->getShapeCollection()->offsetGet($j); + foreach($oPresentation->getSlide($i)->getShapeCollection() as $shape) { + if ($shape instanceof AbstractDrawingAdapter) { $objZip->addFromString( - 'media/' . $imgTemp->getImageIndex() . '/' . pathinfo($imgTemp->getPath(), PATHINFO_BASENAME), - file_get_contents($imgTemp->getPath()) + 'media/' . $shape->getImageIndex() . '/' . pathinfo($shape->getPath(), PATHINFO_BASENAME), + file_get_contents($shape->getPath()) ); } } @@ -99,7 +98,7 @@ protected function writeSerialized(?PhpPresentation $pPhpPresentation = null, $p // Update media links $slideCount = $pPhpPresentation->getSlideCount(); for ($i = 0; $i < $slideCount; ++$i) { - for ($j = 0; $j < $pPhpPresentation->getSlide($i)->getShapeCollection()->count(); ++$j) { + for ($j = 0; $j < count($pPhpPresentation->getSlide($i)->getShapeCollection()); ++$j) { if ($pPhpPresentation->getSlide($i)->getShapeCollection()->offsetGet($j) instanceof AbstractDrawingAdapter) { $imgTemp = $pPhpPresentation->getSlide($i)->getShapeCollection()->offsetGet($j); $imgPath = 'zip://' . $pFilename . '#media/' . $imgTemp->getImageIndex() . '/' . pathinfo($imgTemp->getPath(), PATHINFO_BASENAME); diff --git a/tests/PhpPresentation/Tests/DocumentPropertiesTest.php b/tests/PhpPresentation/Tests/DocumentPropertiesTest.php index 5d0b37259..dd2a4d922 100644 --- a/tests/PhpPresentation/Tests/DocumentPropertiesTest.php +++ b/tests/PhpPresentation/Tests/DocumentPropertiesTest.php @@ -46,6 +46,8 @@ public function testGetSet(): void 'keywords' => '', 'category' => '', 'company' => '', + 'revision' => '', + 'status' => '', ]; foreach ($properties as $key => $val) { diff --git a/tests/PhpPresentation/Tests/PresentationPropertiesTest.php b/tests/PhpPresentation/Tests/PresentationPropertiesTest.php index db361430e..88b0920d7 100644 --- a/tests/PhpPresentation/Tests/PresentationPropertiesTest.php +++ b/tests/PhpPresentation/Tests/PresentationPropertiesTest.php @@ -130,14 +130,36 @@ public function testThumbnail(): void $object = new PresentationProperties(); self::assertNull($object->getThumbnailPath()); - self::assertInstanceOf(PresentationProperties::class, $object->setThumbnailPath('AAAA')); + self::assertInstanceOf(PresentationProperties::class, $object->setThumbnailPath('AAAA', PresentationProperties::THUMBNAIL_FILE)); self::assertNull($object->getThumbnailPath()); self::assertInstanceOf(PresentationProperties::class, $object->setThumbnailPath()); self::assertNull($object->getThumbnailPath()); - self::assertInstanceOf(PresentationProperties::class, $object->setThumbnailPath($imagePath)); + self::assertInstanceOf(PresentationProperties::class, $object->setThumbnailPath($imagePath, PresentationProperties::THUMBNAIL_FILE)); self::assertEquals($imagePath, $object->getThumbnailPath()); + self::assertIsString($object->getThumbnail()); self::assertInstanceOf(PresentationProperties::class, $object->setThumbnailPath()); self::assertEquals($imagePath, $object->getThumbnailPath()); + self::assertIsString($object->getThumbnail()); + } + + public function testThumbnailFileNotExisting(): void + { + $imagePath = PHPPRESENTATION_TESTS_BASE_DIR . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'NotExistingFile.png'; + + $object = new PresentationProperties(); + self::assertInstanceOf(PresentationProperties::class, $object->setThumbnailPath($imagePath, PresentationProperties::THUMBNAIL_FILE)); + self::assertNull($object->getThumbnailPath()); + self::assertNull($object->getThumbnail()); + } + + public function testThumbnailFileData(): void + { + $imagePath = PHPPRESENTATION_TESTS_BASE_DIR . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'PhpPresentationLogo.png'; + + $object = new PresentationProperties(); + self::assertInstanceOf(PresentationProperties::class, $object->setThumbnailPath($imagePath, PresentationProperties::THUMBNAIL_DATA, file_get_contents($imagePath))); + self::assertEquals('', $object->getThumbnailPath()); + self::assertIsString($object->getThumbnail()); } public function testZoom(): void diff --git a/tests/PhpPresentation/Tests/Reader/PowerPoint2007Test.php b/tests/PhpPresentation/Tests/Reader/PowerPoint2007Test.php index 8d04038ef..51b6ac3bf 100644 --- a/tests/PhpPresentation/Tests/Reader/PowerPoint2007Test.php +++ b/tests/PhpPresentation/Tests/Reader/PowerPoint2007Test.php @@ -101,6 +101,8 @@ public function testLoadFile01(): void self::assertEquals('Sample 02 Description', $oPhpPresentation->getDocumentProperties()->getDescription()); self::assertEquals('office 2007 openxml libreoffice odt php', $oPhpPresentation->getDocumentProperties()->getKeywords()); self::assertEquals('Sample Category', $oPhpPresentation->getDocumentProperties()->getCategory()); + self::assertEquals('', $oPhpPresentation->getDocumentProperties()->getRevision()); + self::assertEquals('', $oPhpPresentation->getDocumentProperties()->getStatus()); self::assertIsArray($oPhpPresentation->getDocumentProperties()->getCustomProperties()); self::assertCount(0, $oPhpPresentation->getDocumentProperties()->getCustomProperties()); diff --git a/tests/PhpPresentation/Tests/Shape/GroupTest.php b/tests/PhpPresentation/Tests/Shape/GroupTest.php index 93cbbf7d7..f5b0eefc5 100644 --- a/tests/PhpPresentation/Tests/Shape/GroupTest.php +++ b/tests/PhpPresentation/Tests/Shape/GroupTest.php @@ -38,7 +38,7 @@ public function testConstruct(): void self::assertEquals(0, $object->getOffsetY()); self::assertEquals(0, $object->getExtentX()); self::assertEquals(0, $object->getExtentY()); - self::assertEquals(0, $object->getShapeCollection()->count()); + self::assertCount(0, $object->getShapeCollection()); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Shape\\Group', $object->setWidth(mt_rand(1, 100))); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Shape\\Group', $object->setHeight(mt_rand(1, 100))); } @@ -52,7 +52,7 @@ public function testAdd(): void self::assertInstanceOf('PhpOffice\\PhpPresentation\\Shape\\Line', $object->createLineShape(10, 10, 10, 10)); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Shape\\RichText', $object->createRichTextShape()); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Shape\\Table', $object->createTableShape()); - self::assertEquals(5, $object->getShapeCollection()->count()); + self::assertCount(5, $object->getShapeCollection()); } public function testExtentX(): void diff --git a/tests/PhpPresentation/Tests/Slide/AbstractSlideTest.php b/tests/PhpPresentation/Tests/Slide/AbstractSlideTest.php index d8d67a56f..bb93cc756 100644 --- a/tests/PhpPresentation/Tests/Slide/AbstractSlideTest.php +++ b/tests/PhpPresentation/Tests/Slide/AbstractSlideTest.php @@ -19,7 +19,9 @@ namespace PhpOffice\PhpPresentation\Tests\Slide; +use PhpOffice\PhpPresentation\Shape\Chart; use PhpOffice\PhpPresentation\Shape\RichText; +use PhpOffice\PhpPresentation\Shape\Table; use PhpOffice\PhpPresentation\Slide\AbstractSlide; use PHPUnit\Framework\TestCase; @@ -49,4 +51,36 @@ public function testCollection(): void self::assertIsArray($stub->getShapeCollection()); self::assertCount(count($array), $stub->getShapeCollection()); } + + public function testsearchShapes(): void + { + /** @var AbstractSlide $stub */ + $stub = $this->getMockForAbstractClass('PhpOffice\\PhpPresentation\\Slide\\AbstractSlide'); + + $array = [ + (new RichText())->setName('AAA'), + (new Table())->setName('BBB'), + (new Chart())->setName('AAA'), + ]; + self::assertInstanceOf('PhpOffice\\PhpPresentation\\Slide\\AbstractSlide', $stub->setShapeCollection($array)); + + // Search by Name + $result = $stub->searchShapes('AAA', null); + self::assertIsArray($result); + self::assertCount(2, $result); + self::assertInstanceOf(RichText::class, $result[0]); + self::assertInstanceOf(Chart::class, $result[1]); + + // Search by Name && Type + $result = $stub->searchShapes('AAA', Chart::class); + self::assertIsArray($result); + self::assertCount(1, $result); + self::assertInstanceOf(Chart::class, $result[0]); + + // Search by Type + $result = $stub->searchShapes(null, Table::class); + self::assertIsArray($result); + self::assertCount(1, $result); + self::assertInstanceOf(Table::class, $result[0]); + } } diff --git a/tests/PhpPresentation/Tests/Slide/NoteTest.php b/tests/PhpPresentation/Tests/Slide/NoteTest.php index 5cf4ce020..145b864a0 100644 --- a/tests/PhpPresentation/Tests/Slide/NoteTest.php +++ b/tests/PhpPresentation/Tests/Slide/NoteTest.php @@ -69,13 +69,13 @@ public function testOffset(): void public function testShape(): void { $object = new Note(); - self::assertEquals(0, $object->getShapeCollection()->count()); + self::assertCount(0, $object->getShapeCollection()); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Shape\\RichText', $object->createRichTextShape()); - self::assertEquals(1, $object->getShapeCollection()->count()); + self::assertCount(1, $object->getShapeCollection()); $oRichText = new RichText(); - self::assertInstanceOf('PhpOffice\\PhpPresentation\\Shape\\RichText', $object->addShape($oRichText)); - self::assertEquals(2, $object->getShapeCollection()->count()); + self::assertInstanceOf(Note::class, $object->addShape($oRichText)); + self::assertCount(2, $object->getShapeCollection()); } /** diff --git a/tests/PhpPresentation/Tests/Slide/SlideLayoutTest.php b/tests/PhpPresentation/Tests/Slide/SlideLayoutTest.php index b3d23a42d..daea51b22 100644 --- a/tests/PhpPresentation/Tests/Slide/SlideLayoutTest.php +++ b/tests/PhpPresentation/Tests/Slide/SlideLayoutTest.php @@ -37,7 +37,7 @@ public function testBase(): void $object = new SlideLayout($mockSlideMaster); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Slide\\AbstractSlide', $object); - self::assertInstanceOf('\\ArrayObject', $object->getShapeCollection()); + self::assertIsArray($object->getShapeCollection()); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\ColorMap', $object->colorMap); } diff --git a/tests/PhpPresentation/Tests/Slide/SlideMasterTest.php b/tests/PhpPresentation/Tests/Slide/SlideMasterTest.php index e910ae79a..b79cc1c31 100644 --- a/tests/PhpPresentation/Tests/Slide/SlideMasterTest.php +++ b/tests/PhpPresentation/Tests/Slide/SlideMasterTest.php @@ -38,7 +38,7 @@ public function testBase(): void $object = new SlideMaster(); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Slide\\AbstractSlide', $object); self::assertNull($object->getParent()); - self::assertInstanceOf('\\ArrayObject', $object->getShapeCollection()); + self::assertIsArray($object->getShapeCollection()); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\ColorMap', $object->colorMap); /** @var Color $background */ $background = $object->getBackground(); diff --git a/tests/PhpPresentation/Tests/Style/FontTest.php b/tests/PhpPresentation/Tests/Style/FontTest.php index 711c2da53..ae33838be 100644 --- a/tests/PhpPresentation/Tests/Style/FontTest.php +++ b/tests/PhpPresentation/Tests/Style/FontTest.php @@ -19,6 +19,7 @@ namespace PhpOffice\PhpPresentation\Tests\Style; +use PhpOffice\PhpPresentation\Exception\InvalidParameterException; use PhpOffice\PhpPresentation\Exception\NotAllowedValueException; use PhpOffice\PhpPresentation\Style\Color; use PhpOffice\PhpPresentation\Style\Font; @@ -49,6 +50,18 @@ public function testConstruct(): void self::assertEquals(Font::CAPITALIZATION_NONE, $object->getCapitalization()); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Color', $object->getColor()); self::assertEquals(Color::COLOR_BLACK, $object->getColor()->getARGB()); + self::assertEquals(0, $object->getBaseline()); + } + + /** + * Test get/set Baseline. + */ + public function testBaseline(): void + { + $object = new Font(); + self::assertEquals(0, $object->getBaseline()); + self::assertInstanceOf(Font::class, $object->setBaseline(Font::BASELINE_SUBSCRIPT)); + self::assertEquals(Font::BASELINE_SUBSCRIPT, $object->getBaseline()); } /** @@ -76,6 +89,17 @@ public function testCapitalizationException(): void $object->setCapitalization('Invalid'); } + /** + * Test get/set charset. + */ + public function testCharset(): void + { + $object = new Font(); + self::assertEquals(Font::CHARSET_DEFAULT, $object->getCharset()); + self::assertInstanceOf(Font::class, $object->setCharset(12)); + self::assertEquals(12, $object->getCharset()); + } + /** * Test get/set Character Spacing. */ @@ -134,6 +158,52 @@ public function testName(): void self::assertEquals('Arial', $object->getName()); } + /** + * Test get/set panose. + */ + public function testPanose(): void + { + $object = new Font(); + self::assertEquals('', $object->getPanose()); + self::assertInstanceOf(Font::class, $object->setPanose('4494D72242')); + self::assertEquals('4494D72242', $object->getPanose()); + } + + /** + * Test get/set panose (Exception : Invalid Length). + */ + public function testPanoseExceptionInvalidLength(): void + { + $this->expectException(InvalidParameterException::class); + $this->expectExceptionMessage('The parameter pValue can\'t have the value "12345" (Validation: The length is not equals to 10)'); + + $object = new Font(); + $object->setPanose('12345'); + } + + /** + * Test get/set panose (Exception : Invalid Char). + */ + public function testPanoseExceptionInvalidChar(): void + { + $this->expectException(InvalidParameterException::class); + $this->expectExceptionMessage('The parameter pValue can\'t have the value "4494D7224X" (Validation: The character "X" is not allowed)'); + + $object = new Font(); + $object->setPanose('4494D7224X'); + } + + /** + * Test get/set pitch family. + */ + public function testPitchFamily(): void + { + $object = new Font(); + self::assertEquals(0, $object->getPitchFamily()); + self::assertInstanceOf(Font::class, $object->setPitchFamily(12)); + self::assertEquals(12, $object->getPitchFamily()); + } + /** * Test get/set size. */ @@ -197,10 +267,18 @@ public function testSetIsStriketrough(): void $object = new Font(); self::assertInstanceOf(Font::class, $object->setStrikethrough()); self::assertFalse($object->isStrikethrough()); + self::assertEquals(Font::STRIKE_NONE, $object->getStrikethrough()); + // boolean self::assertInstanceOf(Font::class, $object->setStrikethrough(false)); self::assertFalse($object->isStrikethrough()); + self::assertEquals(Font::STRIKE_NONE, $object->getStrikethrough()); self::assertInstanceOf(Font::class, $object->setStrikethrough(true)); self::assertTrue($object->isStrikethrough()); + self::assertEquals(Font::STRIKE_SINGLE, $object->getStrikethrough()); + // string + self::assertInstanceOf(Font::class, $object->setStrikethrough(Font::STRIKE_DOUBLE)); + self::assertTrue($object->isStrikethrough()); + self::assertEquals(Font::STRIKE_DOUBLE, $object->getStrikethrough()); } /** diff --git a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/DocPropsCoreTest.php b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/DocPropsCoreTest.php index 3a87a2613..5c79a1ee8 100644 --- a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/DocPropsCoreTest.php +++ b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/DocPropsCoreTest.php @@ -25,13 +25,6 @@ class DocPropsCoreTest extends PhpPresentationTestCase { protected $writerName = 'PowerPoint2007'; - public function testRender(): void - { - $this->assertZipFileExists('docProps/core.xml'); - $this->assertZipXmlElementNotExists('docProps/core.xml', '/cp:coreProperties/cp:contentStatus'); - $this->assertIsSchemaECMA376Valid(); - } - public function testDocumentProperties(): void { $expected = 'aAbBcDeE'; @@ -42,7 +35,9 @@ public function testDocumentProperties(): void ->setDescription($expected) ->setSubject($expected) ->setKeywords($expected) - ->setCategory($expected); + ->setCategory($expected) + ->setRevision($expected) + ->setStatus($expected); $this->assertZipFileExists('docProps/core.xml'); $this->assertZipXmlElementExists('docProps/core.xml', '/cp:coreProperties/dc:creator'); @@ -57,6 +52,10 @@ public function testDocumentProperties(): void $this->assertZipXmlElementEquals('docProps/core.xml', '/cp:coreProperties/cp:keywords', $expected); $this->assertZipXmlElementExists('docProps/core.xml', '/cp:coreProperties/cp:category'); $this->assertZipXmlElementEquals('docProps/core.xml', '/cp:coreProperties/cp:category', $expected); + $this->assertZipXmlElementExists('docProps/core.xml', '/cp:coreProperties/cp:revision'); + $this->assertZipXmlElementEquals('docProps/core.xml', '/cp:coreProperties/cp:revision', $expected); + $this->assertZipXmlElementExists('docProps/core.xml', '/cp:coreProperties/cp:contentStatus'); + $this->assertZipXmlElementEquals('docProps/core.xml', '/cp:coreProperties/cp:contentStatus', $expected); $this->assertIsSchemaECMA376Valid(); } @@ -73,7 +72,8 @@ public function testMarkAsFinalFalse(): void { $this->oPresentation->getPresentationProperties()->markAsFinal(false); - $this->assertZipXmlElementNotExists('docProps/core.xml', '/cp:coreProperties/cp:contentStatus'); + $this->assertZipXmlElementExists('docProps/core.xml', '/cp:coreProperties/cp:contentStatus'); + $this->assertZipXmlElementEquals('docProps/core.xml', '/cp:coreProperties/cp:contentStatus', ''); $this->assertIsSchemaECMA376Valid(); } } diff --git a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/DocPropsThumbnailTest.php b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/DocPropsThumbnailTest.php index cd29a9733..ddab8a1cc 100644 --- a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/DocPropsThumbnailTest.php +++ b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/DocPropsThumbnailTest.php @@ -19,6 +19,7 @@ namespace PhpPresentation\Tests\Writer\PowerPoint2007; +use PhpOffice\PhpPresentation\PresentationProperties; use PhpOffice\PhpPresentation\Tests\PhpPresentationTestCase; /** @@ -31,15 +32,40 @@ class DocPropsThumbnailTest extends PhpPresentationTestCase public function testRender(): void { $this->assertZipFileNotExists('docProps/thumbnail.jpeg'); + $this->assertZipXmlElementNotExists('_rels/.rels', '/Relationships/Relationship[@Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"]'); $this->assertIsSchemaECMA376Valid(); } - public function testFeatureThumbnail(): void + public function testFeatureThumbnailFile(): void { $imagePath = PHPPRESENTATION_TESTS_BASE_DIR . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'PhpPresentationLogo.png'; - $this->oPresentation->getPresentationProperties()->setThumbnailPath($imagePath); + $this->oPresentation->getPresentationProperties() + ->setThumbnailPath($imagePath, PresentationProperties::THUMBNAIL_FILE); $this->assertZipFileExists('docProps/thumbnail.jpeg'); + $this->assertZipXmlElementExists('_rels/.rels', '/Relationships/Relationship[@Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"]'); + $this->assertIsSchemaECMA376Valid(); + } + + public function testFeatureThumbnailFileNotExisting(): void + { + $imagePath = PHPPRESENTATION_TESTS_BASE_DIR . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'NotExistingFile.png'; + + $this->oPresentation->getPresentationProperties() + ->setThumbnailPath($imagePath, PresentationProperties::THUMBNAIL_FILE); + $this->assertZipFileNotExists('docProps/thumbnail.jpeg'); + $this->assertZipXmlElementNotExists('_rels/.rels', '/Relationships/Relationship[@Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"]'); + $this->assertIsSchemaECMA376Valid(); + } + + public function testFeatureThumbnailData(): void + { + $imagePath = PHPPRESENTATION_TESTS_BASE_DIR . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'PhpPresentationLogo.png'; + + $this->oPresentation->getPresentationProperties() + ->setThumbnailPath('', PresentationProperties::THUMBNAIL_DATA, file_get_contents($imagePath)); + $this->assertZipFileExists('docProps/thumbnail.jpeg'); + $this->assertZipXmlElementExists('_rels/.rels', '/Relationships/Relationship[@Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"]'); $this->assertIsSchemaECMA376Valid(); } } diff --git a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlideMastersTest.php b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlideMastersTest.php index c4374b6d1..8b57dc7b4 100644 --- a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlideMastersTest.php +++ b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlideMastersTest.php @@ -62,7 +62,7 @@ public function testWriteSlideMasterRelationships(): void ->willReturn($layouts); /** @var ArrayObject $collection */ - $collection = new ArrayObject(); + $collection = array(); $collection[] = new ShapeDrawingFile(); $collection[] = new ShapeDrawingFile(); $collection[] = new ShapeDrawingFile(); diff --git a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlidesTest.php b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlidesTest.php index 9e0640477..652ebd5b4 100644 --- a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlidesTest.php +++ b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlidesTest.php @@ -868,6 +868,53 @@ public function testRichTextHyperlink(): void $this->assertIsSchemaECMA376Valid(); } + public function testRichTextRunFontCharset(): void + { + $latinElement = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:rPr/a:latin'; + $eastAsianElement = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:rPr/a:ea'; + $complexScriptElement = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:rPr/a:cs'; + + $oSlide = $this->oPresentation->getActiveSlide(); + $oRichText = $oSlide->createRichTextShape(); + $oRun = $oRichText->createTextRun('MyText'); + $oRun->getFont()->setCharset(18); + + $oRun->getFont()->setFormat(Font::FORMAT_LATIN); + + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $latinElement); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $latinElement, 'typeface'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $latinElement, 'typeface', 'Calibri'); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $latinElement, 'charset'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $latinElement, 'charset', '12'); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $eastAsianElement); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $complexScriptElement); + $this->assertIsSchemaECMA376Valid(); + + $oRun->getFont()->setFormat(Font::FORMAT_EAST_ASIAN); + $this->resetPresentationFile(); + + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $latinElement); + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $eastAsianElement); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $eastAsianElement, 'typeface'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $eastAsianElement, 'typeface', 'Calibri'); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $eastAsianElement, 'charset'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $eastAsianElement, 'charset', '12'); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $complexScriptElement); + $this->assertIsSchemaECMA376Valid(); + + $oRun->getFont()->setFormat(Font::FORMAT_COMPLEX_SCRIPT); + $this->resetPresentationFile(); + + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $latinElement); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $eastAsianElement); + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $complexScriptElement); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $complexScriptElement, 'typeface'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $complexScriptElement, 'typeface', 'Calibri'); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $complexScriptElement, 'charset'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $complexScriptElement, 'charset', '12'); + $this->assertIsSchemaECMA376Valid(); + } + public function testRichTextRunFontFormat(): void { $latinElement = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:rPr/a:latin'; @@ -907,6 +954,100 @@ public function testRichTextRunFontFormat(): void $this->assertIsSchemaECMA376Valid(); } + public function testRichTextRunFontPanose(): void + { + $latinElement = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:rPr/a:latin'; + $eastAsianElement = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:rPr/a:ea'; + $complexScriptElement = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:rPr/a:cs'; + + $oSlide = $this->oPresentation->getActiveSlide(); + $oRichText = $oSlide->createRichTextShape(); + $oRun = $oRichText->createTextRun('MyText'); + $oRun->getFont()->setPanose('4494D72242'); + + $oRun->getFont()->setFormat(Font::FORMAT_LATIN); + + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $latinElement); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $latinElement, 'typeface'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $latinElement, 'typeface', 'Calibri'); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $latinElement, 'panose'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $latinElement, 'panose', '040409040D0702020402'); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $eastAsianElement); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $complexScriptElement); + $this->assertIsSchemaECMA376Valid(); + + $oRun->getFont()->setFormat(Font::FORMAT_EAST_ASIAN); + $this->resetPresentationFile(); + + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $latinElement); + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $eastAsianElement); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $eastAsianElement, 'typeface'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $eastAsianElement, 'typeface', 'Calibri'); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $eastAsianElement, 'panose'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $eastAsianElement, 'panose', '040409040D0702020402'); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $complexScriptElement); + $this->assertIsSchemaECMA376Valid(); + + $oRun->getFont()->setFormat(Font::FORMAT_COMPLEX_SCRIPT); + $this->resetPresentationFile(); + + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $latinElement); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $eastAsianElement); + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $complexScriptElement); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $complexScriptElement, 'typeface'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $complexScriptElement, 'typeface', 'Calibri'); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $complexScriptElement, 'panose'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $complexScriptElement, 'panose', '040409040D0702020402'); + $this->assertIsSchemaECMA376Valid(); + } + + public function testRichTextRunFontPitchFamily(): void + { + $latinElement = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:rPr/a:latin'; + $eastAsianElement = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:rPr/a:ea'; + $complexScriptElement = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:rPr/a:cs'; + + $oSlide = $this->oPresentation->getActiveSlide(); + $oRichText = $oSlide->createRichTextShape(); + $oRun = $oRichText->createTextRun('MyText'); + $oRun->getFont()->setPitchFamily(42); + + $oRun->getFont()->setFormat(Font::FORMAT_LATIN); + + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $latinElement); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $latinElement, 'typeface'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $latinElement, 'typeface', 'Calibri'); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $latinElement, 'pitchFamily'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $latinElement, 'pitchFamily', '42'); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $eastAsianElement); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $complexScriptElement); + $this->assertIsSchemaECMA376Valid(); + + $oRun->getFont()->setFormat(Font::FORMAT_EAST_ASIAN); + $this->resetPresentationFile(); + + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $latinElement); + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $eastAsianElement); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $eastAsianElement, 'typeface'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $eastAsianElement, 'typeface', 'Calibri'); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $eastAsianElement, 'pitchFamily'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $eastAsianElement, 'pitchFamily', '42'); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $complexScriptElement); + $this->assertIsSchemaECMA376Valid(); + + $oRun->getFont()->setFormat(Font::FORMAT_COMPLEX_SCRIPT); + $this->resetPresentationFile(); + + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $latinElement); + $this->assertZipXmlElementNotExists('ppt/slides/slide1.xml', $eastAsianElement); + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $complexScriptElement); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $complexScriptElement, 'typeface'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $complexScriptElement, 'typeface', 'Calibri'); + $this->assertZipXmlAttributeExists('ppt/slides/slide1.xml', $complexScriptElement, 'pitchFamily'); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $complexScriptElement, 'pitchFamily', '42'); + $this->assertIsSchemaECMA376Valid(); + } + public function testRichTextRunLanguage(): void { $oSlide = $this->oPresentation->getActiveSlide(); diff --git a/tests/PhpPresentation/Tests/_includes/PhpPresentationTestCase.php b/tests/PhpPresentation/Tests/_includes/PhpPresentationTestCase.php index 0fc395d3a..120ffe0c9 100644 --- a/tests/PhpPresentation/Tests/_includes/PhpPresentationTestCase.php +++ b/tests/PhpPresentation/Tests/_includes/PhpPresentationTestCase.php @@ -320,6 +320,18 @@ public function assertZipXmlElementEquals($filePath, $xPath, $value): void self::assertEquals($nodeList->item(0)->nodeValue, $value); } + /** + * @param string $filePath + * @param string $xPath + * @param mixed $value + */ + public function assertZipXmlElementNotEquals($filePath, $xPath, $value): void + { + $this->writePresentationFile($this->oPresentation, $this->writerName); + $nodeList = $this->getXmlNodeList($filePath, $xPath); + self::assertNotEquals($nodeList->item(0)->nodeValue, $value); + } + /** * @param mixed $value */