diff --git a/.gitignore b/.gitignore index afe22ddd1..4cdc9c601 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ Desktop.ini ### Continuous Integration build/ phpunit.xml +php-cs-fixer.phar .php-cs-fixer.cache .phpunit.result.cache composer.phar diff --git a/docs/changes/1.1.0.md b/docs/changes/1.1.0.md index 81ba6ae1e..ebab02d39 100644 --- a/docs/changes/1.1.0.md +++ b/docs/changes/1.1.0.md @@ -17,9 +17,24 @@ - 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 image - [@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 Capitalization, Strikethrough, Pitch Family, Charset & Panose - [@devX2712](https://github.com/devX2712) in [#788](https://github.com/PHPOffice/PHPPresentation/pull/787) + - PowerPoint2007 Reader + - PowerPoint2007 Writer +- Font : Replaced Superscript/Subscript by baseline in PowerPoint2007 Writer - [@devX2712](https://github.com/devX2712) in [#788](https://github.com/PHPOffice/PHPPresentation/pull/787) +- RichText : Support for Vertical Align - [@devX2712](https://github.com/devX2712) in [#788](https://github.com/PHPOffice/PHPPresentation/pull/787) + - PowerPoint2007 Reader + - PowerPoint2007 Writer +- Shadow : Support for Type Inner & Reflection - [@devX2712](https://github.com/devX2712) in [#788](https://github.com/PHPOffice/PHPPresentation/pull/787) + - PowerPoint2007 Reader + - PowerPoint2007 Writer ## 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_04_Table.php b/samples/Sample_04_Table.php index 0dce634c6..e6558d623 100644 --- a/samples/Sample_04_Table.php +++ b/samples/Sample_04_Table.php @@ -85,7 +85,7 @@ $oCell->createTextRun('R2C1'); $oCell->getActiveParagraph()->getAlignment() ->setMarginLeft(30) - ->setTextDirection(\PhpOffice\PhpPresentation\Style\Alignment::TEXT_DIRECTION_VERTICAL_270); + ->setTextDirection(PhpOffice\PhpPresentation\Style\Alignment::TEXT_DIRECTION_VERTICAL_270); $oCell = $row->nextCell(); $oCell->createTextRun('R2C2'); $oCell->getActiveParagraph()->getAlignment() diff --git a/samples/Sample_05_Chart.php b/samples/Sample_05_Chart.php index 201d9a46a..ad9c32f74 100644 --- a/samples/Sample_05_Chart.php +++ b/samples/Sample_05_Chart.php @@ -132,7 +132,7 @@ function fnSlide_BarHorizontal(PhpPresentation $objPHPPresentation): void // Create a bar chart (that should be inserted in a shape) echo date('H:i:s') . ' Create a horizontal bar chart (that should be inserted in a chart shape) ' . EOL; - $barChartHorz = clone $objPHPPresentation->getSlide(1)->getShapeCollection()->offsetGet(1)->getPlotArea()->getType(); + $barChartHorz = clone $objPHPPresentation->getSlide(1)->getShapeCollection()[1]->getPlotArea()->getType(); $barChartHorz->setBarDirection(Bar3D::DIRECTION_HORIZONTAL); // Create templated slide @@ -363,7 +363,7 @@ function fnSlide_Bar3DHorizontal(PhpPresentation $objPHPPresentation): void // Create a bar chart (that should be inserted in a shape) echo date('H:i:s') . ' Create a horizontal bar chart (that should be inserted in a chart shape) ' . EOL; - $bar3DChartHorz = clone $objPHPPresentation->getSlide(5)->getShapeCollection()->offsetGet(1)->getPlotArea()->getType(); + $bar3DChartHorz = clone $objPHPPresentation->getSlide(5)->getShapeCollection()[1]->getPlotArea()->getType(); $bar3DChartHorz->setBarDirection(Bar3D::DIRECTION_HORIZONTAL); // Create templated slide diff --git a/samples/Sample_17_Comment.php b/samples/Sample_17_Comment.php index c9fa84926..d417c4bfd 100644 --- a/samples/Sample_17_Comment.php +++ b/samples/Sample_17_Comment.php @@ -14,13 +14,13 @@ $oSlide1->addShape(clone $oShapeDrawing); $oSlide1->addShape(clone $oShapeRichText); -$oAuthor = new \PhpOffice\PhpPresentation\Shape\Comment\Author(); +$oAuthor = new PhpOffice\PhpPresentation\Shape\Comment\Author(); $oAuthor->setName('Progi1984'); $oAuthor->setInitials('P'); // Add Comment 1 echo date('H:i:s') . ' Add Comment 1' . EOL; -$oComment1 = new \PhpOffice\PhpPresentation\Shape\Comment(); +$oComment1 = new PhpOffice\PhpPresentation\Shape\Comment(); $oComment1->setText('Text A'); $oComment1->setOffsetX(10); $oComment1->setOffsetY(55); @@ -30,7 +30,7 @@ // Add Comment echo date('H:i:s') . ' Add Comment 2' . EOL; -$oComment2 = new \PhpOffice\PhpPresentation\Shape\Comment(); +$oComment2 = new PhpOffice\PhpPresentation\Shape\Comment(); $oComment2->setText('Text B'); $oComment2->setOffsetX(170); $oComment2->setOffsetY(180); diff --git a/samples/Sample_22_ExternalSlide.php b/samples/Sample_22_ExternalSlide.php index 3e89bf3d2..763234a6b 100644 --- a/samples/Sample_22_ExternalSlide.php +++ b/samples/Sample_22_ExternalSlide.php @@ -9,7 +9,7 @@ $objPHPPresentation = new PhpPresentation(); $objPHPPresentation->removeSlideByIndex(0); -$oReader = \PhpOffice\PhpPresentation\IOFactory::createReader('PowerPoint2007'); +$oReader = PhpOffice\PhpPresentation\IOFactory::createReader('PowerPoint2007'); $oPresentation04 = $oReader->load(__DIR__ . '/results/Sample_04_Table.pptx'); foreach ($oPresentation04->getAllSlides() as $oSlide) { diff --git a/samples/Sample_Header.php b/samples/Sample_Header.php index 61796fe6f..803480e29 100644 --- a/samples/Sample_Header.php +++ b/samples/Sample_Header.php @@ -31,7 +31,7 @@ } else { if (is_file(__DIR__ . '/../../Common/src/Common/Autoloader.php')) { include_once __DIR__ . '/../../Common/src/Common/Autoloader.php'; - \PhpOffice\Common\Autoloader::register(); + PhpOffice\Common\Autoloader::register(); } else { throw new Exception('Can not find the vendor or the common folder!'); } @@ -109,7 +109,7 @@ /** * Write documents. * - * @param \PhpOffice\PhpPresentation\PhpPresentation $phpPresentation + * @param PhpPresentation $phpPresentation * @param string $filename * @param array $writers * @@ -180,7 +180,7 @@ function getEndingNotes($writers) /** * Creates a templated slide. */ -function createTemplatedSlide(PHPPresentation $objPHPPresentation): Slide +function createTemplatedSlide(PhpPresentation $objPHPPresentation): Slide { // Create slide $slide = $objPHPPresentation->createSlide(); @@ -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) { @@ -366,11 +366,11 @@ protected function displayShapeInfo(AbstractShape $oShape): void $this->append('
None
'); } else { switch ($oShape->getFill()->getFillType()) { - case \PhpOffice\PhpPresentation\Style\Fill::FILL_NONE: + case PhpOffice\PhpPresentation\Style\Fill::FILL_NONE: $this->append('
None
'); break; - case \PhpOffice\PhpPresentation\Style\Fill::FILL_SOLID: + case PhpOffice\PhpPresentation\Style\Fill::FILL_SOLID: $this->append('
Solid ('); $this->append('Color : #' . $oShape->getFill()->getStartColor()->getRGB()); $this->append(' - Alpha : ' . $oShape->getFill()->getStartColor()->getAlpha() . '%'); @@ -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 083154379..bbe9de54d 100644 --- a/src/PhpPresentation/AbstractShape.php +++ b/src/PhpPresentation/AbstractShape.php @@ -20,6 +20,7 @@ namespace PhpOffice\PhpPresentation; use PhpOffice\PhpPresentation\Exception\ShapeContainerAlreadyAssignedException; +use PhpOffice\PhpPresentation\Shape\Group; use PhpOffice\PhpPresentation\Shape\Hyperlink; use PhpOffice\PhpPresentation\Shape\Placeholder; use PhpOffice\PhpPresentation\Style\Border; @@ -109,6 +110,13 @@ abstract class AbstractShape implements ComparableInterface */ private $hashIndex; + /** + * Name. + * + * @var string + */ + protected $name = ''; + /** * Create a new self. */ @@ -118,7 +126,8 @@ public function __construct() $this->fill = new Fill(); $this->shadow = new Shadow(); $this->border = new Border(); - $this->border->setLineStyle(Style\Border::LINE_NONE); + + $this->border->setLineStyle(Border::LINE_NONE); } /** @@ -127,9 +136,20 @@ public function __construct() public function __clone() { $this->container = null; - $this->fill = clone $this->fill; + $this->name = $this->name; $this->border = clone $this->border; - $this->shadow = clone $this->shadow; + if (isset($this->fill)) { + $this->fill = clone $this->fill; + } + if (isset($this->shadow)) { + $this->shadow = clone $this->shadow; + } + if (isset($this->placeholder)) { + $this->placeholder = clone $this->placeholder; + } + if (isset($this->hyperlink)) { + $this->hyperlink = clone $this->hyperlink; + } } /** @@ -153,21 +173,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->unsetShape($key); $this->container = null; break; } - $iterator->next(); } // Set new \PhpOffice\PhpPresentation\Slide @@ -180,6 +197,26 @@ public function setContainer(?ShapeContainerInterface $pValue = null, $pOverride return $this; } + /** + * Get Name. + */ + public function getName(): string + { + return $this->name; + } + + /** + * Set Name. + * + * @return static + */ + public function setName(string $pValue = ''): self + { + $this->name = $pValue; + + return $this; + } + /** * Get OffsetX. */ diff --git a/src/PhpPresentation/DocumentProperties.php b/src/PhpPresentation/DocumentProperties.php index 7c48cef1d..bd0b4a8b6 100644 --- a/src/PhpPresentation/DocumentProperties.php +++ b/src/PhpPresentation/DocumentProperties.php @@ -101,6 +101,20 @@ class DocumentProperties */ private $company; + /** + * Revision. + * + * @var string + */ + private $revision; + + /** + * Status. + * + * @var string + */ + private $status; + /** * Custom Properties. * @@ -124,6 +138,8 @@ public function __construct() $this->keywords = ''; $this->category = ''; $this->company = 'Microsoft Corporation'; + $this->revision = ''; + $this->status = ''; } /** @@ -141,7 +157,7 @@ public function getCreator() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\DocumentProperties + * @return DocumentProperties */ public function setCreator($pValue = '') { @@ -165,7 +181,7 @@ public function getLastModifiedBy() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\DocumentProperties + * @return DocumentProperties */ public function setLastModifiedBy($pValue = '') { @@ -189,7 +205,7 @@ public function getCreated() * * @param int $pValue * - * @return \PhpOffice\PhpPresentation\DocumentProperties + * @return DocumentProperties */ public function setCreated($pValue = null) { @@ -216,7 +232,7 @@ public function getModified() * * @param int $pValue * - * @return \PhpOffice\PhpPresentation\DocumentProperties + * @return DocumentProperties */ public function setModified($pValue = null) { @@ -243,7 +259,7 @@ public function getTitle() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\DocumentProperties + * @return DocumentProperties */ public function setTitle($pValue = '') { @@ -267,7 +283,7 @@ public function getDescription() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\DocumentProperties + * @return DocumentProperties */ public function setDescription($pValue = '') { @@ -291,7 +307,7 @@ public function getSubject() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\DocumentProperties + * @return DocumentProperties */ public function setSubject($pValue = '') { @@ -315,7 +331,7 @@ public function getKeywords() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\DocumentProperties + * @return DocumentProperties */ public function setKeywords($pValue = '') { @@ -339,7 +355,7 @@ public function getCategory() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\DocumentProperties + * @return DocumentProperties */ public function setCategory($pValue = '') { @@ -363,7 +379,7 @@ public function getCompany() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\DocumentProperties + * @return DocumentProperties */ public function setCompany($pValue = '') { @@ -453,4 +469,40 @@ public function setCustomProperty(string $propertyName, $propertyValue = '', ?st return $this; } + + /** + * Get Revision. + */ + public function getRevision(): string + { + return $this->revision; + } + + /** + * Set Revision. + */ + public function setRevision(string $pValue = ''): self + { + $this->revision = $pValue; + + return $this; + } + + /** + * Get Status. + */ + public function getStatus(): string + { + return $this->status; + } + + /** + * Set Status. + */ + public function setStatus(string $pValue = ''): self + { + $this->status = $pValue; + + return $this; + } } diff --git a/src/PhpPresentation/Exception/InvalidParameterException.php b/src/PhpPresentation/Exception/InvalidParameterException.php index 961809623..5a426ea61 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 c10c915f8..dce8f439d 100644 --- a/src/PhpPresentation/PresentationProperties.php +++ b/src/PhpPresentation/PresentationProperties.php @@ -30,6 +30,9 @@ class PresentationProperties public const VIEW_SLIDE_SORTER = 'sldSorterView'; public const VIEW_SLIDE_THUMBNAIL = 'sldThumbnailView'; + public const THUMBNAIL_FILE = 'file'; + public const THUMBNAIL_DATA = 'data'; + /** * @var array */ @@ -70,10 +73,20 @@ class PresentationProperties protected $markAsFinal = false; /** - * @var null|string + * @var null|string Define the thumbnail content (if content into zip file) */ protected $thumbnail; + /** + * @var null|string Define the thumbnail place + */ + protected $thumbnailPath; + + /** + * @var string Define if thumbnail is out of PPT or previouly store into PPT + */ + protected $thumbnailType = self::THUMBNAIL_FILE; + /** * Zoom. * @@ -113,21 +126,57 @@ public function setLoopContinuouslyUntilEsc(bool $value = false): self */ public function getThumbnailPath(): ?string { - return $this->thumbnail; + return $this->thumbnailPath; + } + + /** + * Return the content of thumbnail. + */ + public function getThumbnail(): ?string + { + // Return content of local file + if ($this->getThumbnailType() == self::THUMBNAIL_FILE) { + if ($this->getThumbnailPath()) { + return file_get_contents($this->getThumbnailPath()); + } + + return null; + } + + // Return content of image stored into zip file + if ($this->getThumbnailType() == self::THUMBNAIL_DATA) { + return $this->thumbnail; + } + + return null; } /** * Define the path for the thumbnail file / preview picture. */ - public function setThumbnailPath(string $path = ''): self + public function setThumbnailPath(string $path = '', string $type = self::THUMBNAIL_FILE, ?string $content = null): self { - if (file_exists($path)) { - $this->thumbnail = $path; + if (file_exists($path) && $type == self::THUMBNAIL_FILE) { + $this->thumbnailPath = $path; + $this->thumbnailType = $type; + } + if ($content != '' && $type == self::THUMBNAIL_DATA) { + $this->thumbnailPath = ''; + $this->thumbnailType = $type; + $this->thumbnail = $content; } return $this; } + /** + * Return the thumbnail type. + */ + public function getThumbnailType(): string + { + return $this->thumbnailType; + } + /** * Mark a document as final. */ diff --git a/src/PhpPresentation/Reader/ODPresentation.php b/src/PhpPresentation/Reader/ODPresentation.php index 0261b3689..579fab676 100644 --- a/src/PhpPresentation/Reader/ODPresentation.php +++ b/src/PhpPresentation/Reader/ODPresentation.php @@ -32,6 +32,7 @@ use PhpOffice\PhpPresentation\Shape\Drawing\Gd; use PhpOffice\PhpPresentation\Shape\RichText; use PhpOffice\PhpPresentation\Shape\RichText\Paragraph; +use PhpOffice\PhpPresentation\Slide\Background\Color as BackgroundColor; use PhpOffice\PhpPresentation\Slide\Background\Image; use PhpOffice\PhpPresentation\Style\Alignment; use PhpOffice\PhpPresentation\Style\Bullet; @@ -71,7 +72,7 @@ class ODPresentation implements ReaderInterface protected $arrayCommonStyles = []; /** - * @var \PhpOffice\Common\XMLReader + * @var XMLReader */ protected $oXMLReader; @@ -258,7 +259,7 @@ protected function loadStyle(DOMElement $nodeStyle): bool if ($nodeDrawingPageProps instanceof DOMElement) { // Read Background Color if ($nodeDrawingPageProps->hasAttribute('draw:fill-color') && 'solid' == $nodeDrawingPageProps->getAttribute('draw:fill')) { - $oBackground = new \PhpOffice\PhpPresentation\Slide\Background\Color(); + $oBackground = new BackgroundColor(); $oColor = new Color(); $oColor->setRGB(substr($nodeDrawingPageProps->getAttribute('draw:fill-color'), -6)); $oBackground->setColor($oColor); diff --git a/src/PhpPresentation/Reader/PowerPoint2007.php b/src/PhpPresentation/Reader/PowerPoint2007.php index 763848c92..140c2f4a5 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; @@ -154,6 +155,11 @@ protected function loadFile(string $pFilename): PhpPresentation $this->loadDocumentProperties($docPropsCore); } + $docThumbnail = $this->oZip->getFromName('_rels/.rels'); + if ($docThumbnail !== false) { + $this->loadThumbnailProperties($docThumbnail); + } + $docPropsCustom = $this->oZip->getFromName('docProps/custom.xml'); if (false !== $docPropsCustom) { $this->loadCustomProperties($docPropsCustom); @@ -223,6 +229,8 @@ protected function loadDocumentProperties(string $sPart): void '/cp:coreProperties/cp:category' => 'setCategory', '/cp:coreProperties/dcterms:created' => 'setCreated', '/cp:coreProperties/dcterms:modified' => 'setModified', + '/cp:coreProperties/cp:revision' => 'setRevision', + '/cp:coreProperties/cp:contentStatus' => 'setStatus', ]; $oProperties = $this->oPhpPresentation->getDocumentProperties(); foreach ($arrayProperties as $path => $property) { @@ -239,6 +247,23 @@ protected function loadDocumentProperties(string $sPart): void } } + /** + * Read information of the document thumbnail. + */ + protected function loadThumbnailProperties(string $sPart): void + { + $xmlReader = new XMLReader(); + $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('', PresentationProperties::THUMBNAIL_DATA, $this->oZip->getFromName($path)); + } + } + /** * Read Custom Properties. */ @@ -849,45 +874,63 @@ protected function loadShapeDrawing(XMLReader $document, DOMElement $node, Abstr $oShape->setHeight(CommonDrawing::emuToPixels((int) $oElement->getAttribute('cy'))); } } - + // Load shape effects $oElement = $document->getElement('p:spPr/a:effectLst', $node); if ($oElement instanceof DOMElement) { - $oShape->getShadow()->setVisible(true); + $oShape->setShadow( + $this->loadShadow($document, $oElement) + ); + } + $oSlide->addShape($oShape); + } - $oSubElement = $document->getElement('a:outerShdw', $oElement); - if ($oSubElement instanceof DOMElement) { - if ($oSubElement->hasAttribute('blurRad')) { - $oShape->getShadow()->setBlurRadius(CommonDrawing::emuToPixels((int) $oSubElement->getAttribute('blurRad'))); - } - if ($oSubElement->hasAttribute('dist')) { - $oShape->getShadow()->setDistance(CommonDrawing::emuToPixels((int) $oSubElement->getAttribute('dist'))); - } - if ($oSubElement->hasAttribute('dir')) { - $oShape->getShadow()->setDirection((int) CommonDrawing::angleToDegrees((int) $oSubElement->getAttribute('dir'))); - } - if ($oSubElement->hasAttribute('algn')) { - $oShape->getShadow()->setAlignment($oSubElement->getAttribute('algn')); - } - } + /** + * Load Shadow for shape or paragraph. + */ + protected function loadShadow(XMLReader $document, DOMElement $node): ?Shadow + { + 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(); + $oShadow->setVisible(true); + $oShadow->setType($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')); + } - $oSubElement = $document->getElement('a:outerShdw/a:srgbClr', $oElement); - if ($oSubElement instanceof DOMElement) { - if ($oSubElement->hasAttribute('val')) { - $oColor = new Color(); - $oColor->setRGB($oSubElement->getAttribute('val')); - $oShape->getShadow()->setColor($oColor); - } - } + // 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); + } - $oSubElement = $document->getElement('a:outerShdw/a:srgbClr/a:alpha', $oElement); - if ($oSubElement instanceof DOMElement) { - if ($oSubElement->hasAttribute('val')) { - $oShape->getShadow()->setAlpha((int) $oSubElement->getAttribute('val') / 1000); + $oShadow->setColor($oColor); + } + + return $oShadow; } } } - $oSlide->addShape($oShape); + return null; } /** @@ -895,9 +938,6 @@ protected function loadShapeDrawing(XMLReader $document, DOMElement $node, Abstr */ protected function loadShapeRichText(XMLReader $document, DOMElement $node, $oSlide): void { - if (!$document->elementExists('p:txBody/a:p/a:r', $node)) { - return; - } // Core $oShape = $oSlide->createRichTextShape(); $oShape->setParagraphs([]); @@ -906,6 +946,11 @@ protected function loadShapeRichText(XMLReader $document, DOMElement $node, $oSl $this->fileRels = $oSlide->getRelsIndex(); } + $oElement = $document->getElement('p:nvSpPr/p:cNvPr', $node); + if ($oElement instanceof DOMElement) { + $oShape->setName($oElement->hasAttribute('name') ? $oElement->getAttribute('name') : ''); + } + $oElement = $document->getElement('p:spPr/a:xfrm', $node); if ($oElement instanceof DOMElement && $oElement->hasAttribute('rot')) { $oShape->setRotation((int) CommonDrawing::angleToDegrees((int) $oElement->getAttribute('rot'))); @@ -939,6 +984,34 @@ protected function loadShapeRichText(XMLReader $document, DOMElement $node, $oSl } } + // Load shape effects + $oElement = $document->getElement('p:spPr/a:effectLst', $node); + if ($oElement instanceof DOMElement) { + $oShape->setShadow( + $this->loadShadow($document, $oElement) + ); + } + + // FBU-20210202+ Read body definitions + $bodyPr = $document->getElement('p:txBody/a:bodyPr', $node); + 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('anchorCtr')) { + $oShape->setVerticalAlignCenter((int) $bodyPr->getAttribute('anchorCtr')); + } + } + $arrayElements = $document->getElements('p:txBody/a:p', $node); foreach ($arrayElements as $oElement) { if ($oElement instanceof DOMElement) { @@ -946,6 +1019,13 @@ protected function loadShapeRichText(XMLReader $document, DOMElement $node, $oSl } } + $oElement = $document->getElement('p:spPr', $node); + if ($oElement instanceof DOMElement) { + $oShape->setFill( + $this->loadStyleFill($document, $oElement) + ); + } + if (count($oShape->getParagraphs()) > 0) { $oShape->setActiveParagraph(0); } @@ -1201,7 +1281,7 @@ protected function loadParagraph(XMLReader $document, DOMElement $oElement, $oSh $oText->getFont()->setItalic('true' == $att || '1' == $att ? true : false); } if ($oElementrPr->hasAttribute('strike')) { - $oText->getFont()->setStrikethrough('noStrike' == $oElementrPr->getAttribute('strike') ? false : true); + $oText->getFont()->setStrikethrough($oElementrPr->getAttribute('strike')); } if ($oElementrPr->hasAttribute('sz')) { $oText->getFont()->setSize((int) ((int) $oElementrPr->getAttribute('sz') / 100)); @@ -1212,6 +1292,12 @@ protected function loadParagraph(XMLReader $document, DOMElement $oElement, $oSh if ($oElementrPr->hasAttribute('cap')) { $oText->getFont()->setCapitalization($oElementrPr->getAttribute('cap')); } + if ($oElementrPr->hasAttribute('lang')) { + $oText->setLanguage($oElementrPr->getAttribute('lang')); + } + if ($oElementrPr->hasAttribute('baseline')) { + $oText->getFont()->setBaseline((int) $oElementrPr->getAttribute('baseline')); + } // Color $oElementSrgbClr = $document->getElement('a:solidFill/a:srgbClr', $oElementrPr); if (is_object($oElementSrgbClr) && $oElementSrgbClr->hasAttribute('val')) { @@ -1246,9 +1332,22 @@ protected function loadParagraph(XMLReader $document, DOMElement $oElement, $oSh if (is_object($oElementFontFormat) && $oElementFontFormat->hasAttribute('typeface')) { $oText->getFont()->setName($oElementFontFormat->getAttribute('typeface')); } - - //} else { - // $oText = $oParagraph->createText(); + // Font definition + $oElementFont = $document->getElement('a:latin', $oElementrPr); + 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')); + } + } $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..df58d9551 100644 --- a/src/PhpPresentation/Reader/Serialized.php +++ b/src/PhpPresentation/Reader/Serialized.php @@ -92,14 +92,13 @@ 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) { - 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); - if ($imgTemp instanceof DrawingFile) { - $imgTemp->setPath($imgPath, false); + foreach ($file->getSlide($i)->getShapeCollection() as $shape) { + if ($shape instanceof AbstractDrawingAdapter) { + $imgPath = 'zip://' . $pFilename . '#media/' . $shape->getImageIndex() . '/' . pathinfo($shape->getPath(), PATHINFO_BASENAME); + if ($shape instanceof DrawingFile) { + $shape->setPath($imgPath, false); } else { - $imgTemp->setPath($imgPath); + $shape->setPath($imgPath); } } } 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/Chart/Legend.php b/src/PhpPresentation/Shape/Chart/Legend.php index 8798ea555..2d31708fc 100644 --- a/src/PhpPresentation/Shape/Chart/Legend.php +++ b/src/PhpPresentation/Shape/Chart/Legend.php @@ -89,21 +89,21 @@ class Legend implements ComparableInterface /** * Border. * - * @var \PhpOffice\PhpPresentation\Style\Border + * @var Border */ private $border; /** * Fill. * - * @var \PhpOffice\PhpPresentation\Style\Fill + * @var Fill */ private $fill; /** * Alignment. * - * @var \PhpOffice\PhpPresentation\Style\Alignment + * @var Alignment */ private $alignment; @@ -133,7 +133,7 @@ public function isVisible() * * @param bool $value * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Legend + * @return Legend */ public function setVisible($value = true) { @@ -157,7 +157,7 @@ public function getPosition() * * @param string $value * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Legend + * @return Legend */ public function setPosition($value = self::POSITION_RIGHT) { @@ -261,7 +261,7 @@ public function setFont(?Font $pFont = null): self /** * Get Border. * - * @return \PhpOffice\PhpPresentation\Style\Border + * @return Border */ public function getBorder() { @@ -271,7 +271,7 @@ public function getBorder() /** * Set Border. * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Legend + * @return Legend */ public function setBorder(Border $border) { @@ -283,7 +283,7 @@ public function setBorder(Border $border) /** * Get Fill. * - * @return \PhpOffice\PhpPresentation\Style\Fill + * @return Fill */ public function getFill() { @@ -293,7 +293,7 @@ public function getFill() /** * Set Fill. * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Legend + * @return Legend */ public function setFill(Fill $fill) { @@ -305,7 +305,7 @@ public function setFill(Fill $fill) /** * Get alignment. * - * @return \PhpOffice\PhpPresentation\Style\Alignment + * @return Alignment */ public function getAlignment() { @@ -315,7 +315,7 @@ public function getAlignment() /** * Set alignment. * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Legend + * @return Legend */ public function setAlignment(Alignment $alignment) { diff --git a/src/PhpPresentation/Shape/Chart/Title.php b/src/PhpPresentation/Shape/Chart/Title.php index 69494b785..a06c74468 100644 --- a/src/PhpPresentation/Shape/Chart/Title.php +++ b/src/PhpPresentation/Shape/Chart/Title.php @@ -73,14 +73,14 @@ class Title implements ComparableInterface /** * Alignment. * - * @var \PhpOffice\PhpPresentation\Style\Alignment + * @var Alignment */ private $alignment; /** * Font. * - * @var \PhpOffice\PhpPresentation\Style\Font + * @var Font */ private $font; @@ -117,7 +117,7 @@ public function isVisible() * * @param bool $value * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Title + * @return Title */ public function setVisible($value = true) { @@ -141,7 +141,7 @@ public function getText() * * @param string $value * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Title + * @return Title */ public function setText($value = null) { @@ -245,7 +245,7 @@ public function setFont(?Font $pFont = null): self /** * Get alignment. * - * @return \PhpOffice\PhpPresentation\Style\Alignment + * @return Alignment */ public function getAlignment() { @@ -255,7 +255,7 @@ public function getAlignment() /** * Set alignment. * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Title + * @return Title */ public function setAlignment(Alignment $alignment) { diff --git a/src/PhpPresentation/Shape/Chart/Type/AbstractTypeBar.php b/src/PhpPresentation/Shape/Chart/Type/AbstractTypeBar.php index 751b23371..8b671c74e 100644 --- a/src/PhpPresentation/Shape/Chart/Type/AbstractTypeBar.php +++ b/src/PhpPresentation/Shape/Chart/Type/AbstractTypeBar.php @@ -67,7 +67,7 @@ abstract class AbstractTypeBar extends AbstractType * * @param string $value * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Type\AbstractTypeBar + * @return AbstractTypeBar */ public function setBarDirection($value = self::DIRECTION_VERTICAL) { @@ -91,7 +91,7 @@ public function getBarDirection() * * @param string $value * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Type\AbstractTypeBar + * @return AbstractTypeBar */ public function setBarGrouping($value = self::GROUPING_CLUSTERED) { diff --git a/src/PhpPresentation/Shape/Chart/View3D.php b/src/PhpPresentation/Shape/Chart/View3D.php index b6c0a4996..64111db63 100644 --- a/src/PhpPresentation/Shape/Chart/View3D.php +++ b/src/PhpPresentation/Shape/Chart/View3D.php @@ -97,7 +97,7 @@ public function getRotationX() * * @param int $pValue * - * @return \PhpOffice\PhpPresentation\Shape\Chart\View3D + * @return View3D */ public function setRotationX($pValue = 0) { @@ -121,7 +121,7 @@ public function getRotationY() * * @param int $pValue * - * @return \PhpOffice\PhpPresentation\Shape\Chart\View3D + * @return View3D */ public function setRotationY($pValue = 0) { @@ -145,7 +145,7 @@ public function hasRightAngleAxes() * * @param bool $value * - * @return \PhpOffice\PhpPresentation\Shape\Chart\View3D + * @return View3D */ public function setRightAngleAxes($value = true) { @@ -169,7 +169,7 @@ public function getPerspective() * * @param int $value * - * @return \PhpOffice\PhpPresentation\Shape\Chart\View3D + * @return View3D */ public function setPerspective($value = 30) { diff --git a/src/PhpPresentation/Shape/Group.php b/src/PhpPresentation/Shape/Group.php index 4945f1561..1ceaf55e5 100644 --- a/src/PhpPresentation/Shape/Group.php +++ b/src/PhpPresentation/Shape/Group.php @@ -19,19 +19,14 @@ namespace PhpOffice\PhpPresentation\Shape; -use ArrayObject; 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 +45,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 59fc22140..7aafe3c10 100644 --- a/src/PhpPresentation/Shape/RichText.php +++ b/src/PhpPresentation/Shape/RichText.php @@ -21,6 +21,7 @@ use PhpOffice\PhpPresentation\AbstractShape; use PhpOffice\PhpPresentation\ComparableInterface; +use PhpOffice\PhpPresentation\Exception\NotAllowedValueException; use PhpOffice\PhpPresentation\Exception\OutOfBoundsException; use PhpOffice\PhpPresentation\Shape\RichText\Paragraph; use PhpOffice\PhpPresentation\Shape\RichText\TextElementInterface; @@ -44,12 +45,16 @@ class RichText extends AbstractShape implements ComparableInterface public const OVERFLOW_CLIP = 'clip'; public const OVERFLOW_OVERFLOW = 'overflow'; + /** Vertical alignment center */ + public const VALIGN_CENTER = 1; + public const VALIGN_NOTCENTER = 0; + /** * Rich text paragraphs. * * @var array */ - private $richTextParagraphs; + private $richTextParagraphs = []; /** * Active paragraph. @@ -170,6 +175,13 @@ class RichText extends AbstractShape implements ComparableInterface */ private $lnSpcReduction; + /** + * Define vertical text center position into shape (center,not center). + * + * @var int + */ + private $verticalAlignCenter = self::VALIGN_NOTCENTER; + /** * Create a new \PhpOffice\PhpPresentation\Shape\RichText instance. */ @@ -184,6 +196,19 @@ public function __construct() parent::__construct(); } + /** + * Magic Method : clone. + */ + public function __clone() + { + // Call perent clonage for heritage + parent::__clone(); + // Clone each paragraph + foreach ($this->richTextParagraphs as &$paragraph) { + $paragraph = clone $paragraph; + } + } + /** * Get active paragraph index. */ @@ -471,6 +496,35 @@ public function setVertical(bool $value = false): self return $this; } + /** + * Define the vertical alignment if centered or not. + * + * @param int $value 1=center 0=not + * + * @see self::VALIGN_CENTER, self::VALIGN_NOTCENTER + */ + public function setVerticalAlignCenter(int $value): self + { + if (!in_array( + $value, + [self::VALIGN_CENTER, self::VALIGN_NOTCENTER] + )) { + throw new NotAllowedValueException((string) $value, [(string) self::VALIGN_CENTER, (string) self::VALIGN_NOTCENTER]); + } + + $this->verticalAlignCenter = $value; + + return $this; + } + + /** + * Get the vertical alignment center. + */ + public function getVerticalAlignCenter(): int + { + return $this->verticalAlignCenter; + } + /** * Get columns. */ @@ -641,6 +695,7 @@ public function getHashCode(): string . $this->leftInset . $this->rightInset . $this->topInset + . $this->verticalAlignCenter . parent::getHashCode() . __CLASS__ ); diff --git a/src/PhpPresentation/Shape/RichText/Paragraph.php b/src/PhpPresentation/Shape/RichText/Paragraph.php index b1d80f8d2..2eb173a62 100644 --- a/src/PhpPresentation/Shape/RichText/Paragraph.php +++ b/src/PhpPresentation/Shape/RichText/Paragraph.php @@ -97,6 +97,17 @@ public function __construct() $this->bulletStyle = new Bullet(); } + /** + * Magic Method : clone. + */ + public function __clone() + { + // Clone each text + foreach ($this->richTextElements as &$rtElement) { + $rtElement = clone $rtElement; + } + } + /** * Get alignment. */ diff --git a/src/PhpPresentation/Shape/RichText/Run.php b/src/PhpPresentation/Shape/RichText/Run.php index ba8fc12a5..a9f99fe3e 100644 --- a/src/PhpPresentation/Shape/RichText/Run.php +++ b/src/PhpPresentation/Shape/RichText/Run.php @@ -29,18 +29,16 @@ class Run extends TextElement implements TextElementInterface /** * Font. * - * @var \PhpOffice\PhpPresentation\Style\Font + * @var Font */ private $font; /** - * 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(); } @@ -56,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) { @@ -69,8 +65,6 @@ public function setFont(?Font $pFont = null) /** * Get hash code. - * - * @return string Hash code */ public function getHashCode(): string { diff --git a/src/PhpPresentation/Shape/RichText/TextElement.php b/src/PhpPresentation/Shape/RichText/TextElement.php index 709860ffb..e240a01e2 100644 --- a/src/PhpPresentation/Shape/RichText/TextElement.php +++ b/src/PhpPresentation/Shape/RichText/TextElement.php @@ -72,7 +72,7 @@ public function getText() * * @param string $pText Text value * - * @return \PhpOffice\PhpPresentation\Shape\RichText\TextElementInterface + * @return TextElementInterface */ public function setText($pText = '') { @@ -106,7 +106,7 @@ public function getHyperlink(): Hyperlink /** * Set Hyperlink. * - * @return \PhpOffice\PhpPresentation\Shape\RichText\TextElement + * @return TextElement */ public function setHyperlink(?Hyperlink $pHyperlink = null) { diff --git a/src/PhpPresentation/Shape/RichText/TextElementInterface.php b/src/PhpPresentation/Shape/RichText/TextElementInterface.php index af2485bb0..f0edad48c 100644 --- a/src/PhpPresentation/Shape/RichText/TextElementInterface.php +++ b/src/PhpPresentation/Shape/RichText/TextElementInterface.php @@ -36,7 +36,7 @@ public function getText(); * * @param string $pText Text value * - * @return \PhpOffice\PhpPresentation\Shape\RichText\TextElementInterface + * @return TextElementInterface */ public function setText($pText = ''); @@ -55,7 +55,7 @@ public function getLanguage(); /** * @param string $lang * - * @return \PhpOffice\PhpPresentation\Shape\RichText\TextElementInterface + * @return TextElementInterface */ public function setLanguage($lang); diff --git a/src/PhpPresentation/Shape/Table/Cell.php b/src/PhpPresentation/Shape/Table/Cell.php index 47bf1e6e6..d5e5251c8 100644 --- a/src/PhpPresentation/Shape/Table/Cell.php +++ b/src/PhpPresentation/Shape/Table/Cell.php @@ -48,14 +48,14 @@ class Cell implements ComparableInterface /** * Fill. * - * @var \PhpOffice\PhpPresentation\Style\Fill + * @var Fill */ private $fill; /** * Borders. * - * @var \PhpOffice\PhpPresentation\Style\Borders + * @var Borders */ private $borders; @@ -178,7 +178,7 @@ public function createParagraph(): Paragraph * * @param TextElementInterface $pText Rich text element * - * @return \PhpOffice\PhpPresentation\Shape\Table\Cell + * @return Cell */ public function addText(?TextElementInterface $pText = null) { @@ -276,7 +276,7 @@ public function setParagraphs(array $paragraphs = []): self /** * Get fill. * - * @return \PhpOffice\PhpPresentation\Style\Fill + * @return Fill */ public function getFill() { @@ -286,7 +286,7 @@ public function getFill() /** * Set fill. * - * @return \PhpOffice\PhpPresentation\Shape\Table\Cell + * @return Cell */ public function setFill(Fill $fill) { @@ -298,7 +298,7 @@ public function setFill(Fill $fill) /** * Get borders. * - * @return \PhpOffice\PhpPresentation\Style\Borders + * @return Borders */ public function getBorders() { @@ -308,7 +308,7 @@ public function getBorders() /** * Set borders. * - * @return \PhpOffice\PhpPresentation\Shape\Table\Cell + * @return Cell */ public function setBorders(Borders $borders) { diff --git a/src/PhpPresentation/ShapeContainerInterface.php b/src/PhpPresentation/ShapeContainerInterface.php index a347c358e..5fde0573d 100644 --- a/src/PhpPresentation/ShapeContainerInterface.php +++ b/src/PhpPresentation/ShapeContainerInterface.php @@ -36,10 +36,17 @@ public function getShapeCollection(); /** * Add shape to slide. * - * @return AbstractShape + * @return static */ public function addShape(AbstractShape $shape); + /** + * Unset shape from the collection. + * + * @return static + */ + public function unsetShape(int $key); + /** * Get X Offset. */ diff --git a/src/PhpPresentation/Slide.php b/src/PhpPresentation/Slide.php index 345e24bba..3b0a9218f 100644 --- a/src/PhpPresentation/Slide.php +++ b/src/PhpPresentation/Slide.php @@ -19,7 +19,6 @@ namespace PhpOffice\PhpPresentation; -use ArrayObject; use PhpOffice\PhpPresentation\Slide\AbstractSlide; use PhpOffice\PhpPresentation\Slide\Note; use PhpOffice\PhpPresentation\Slide\SlideLayout; @@ -74,8 +73,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 @@ -123,7 +120,7 @@ public function getSlideMasterId() * * @param int $masterId * - * @return \PhpOffice\PhpPresentation\Slide + * @return Slide */ public function setSlideMasterId($masterId = 1) { @@ -132,10 +129,26 @@ public function setSlideMasterId($masterId = 1) return $this; } + public function __clone() + { + // Set parent + $this->parent = clone $this->parent; + // Shape collection + foreach ($this->shapeCollection as &$shape) { + $shape = clone $shape; + } + // Transition + if (isset($this->slideTransition)) { + $this->slideTransition = clone $this->slideTransition; + } + // Note + $this->slideNote = clone $this->slideNote; + } + /** * Copy slide (!= clone!). * - * @return \PhpOffice\PhpPresentation\Slide + * @return Slide */ public function copy() { @@ -198,7 +211,7 @@ public function setIsVisible($value = true) /** * Add an animation to the slide. * - * @param \PhpOffice\PhpPresentation\Slide\Animation $animation + * @param Slide\Animation $animation * * @return Slide */ diff --git a/src/PhpPresentation/Slide/AbstractSlide.php b/src/PhpPresentation/Slide/AbstractSlide.php index b3d6fedfd..9c93c3283 100644 --- a/src/PhpPresentation/Slide/AbstractSlide.php +++ b/src/PhpPresentation/Slide/AbstractSlide.php @@ -19,8 +19,6 @@ namespace PhpOffice\PhpPresentation\Slide; -use ArrayObject; -use PhpOffice\PhpPresentation\AbstractShape; use PhpOffice\PhpPresentation\ComparableInterface; use PhpOffice\PhpPresentation\GeometryCalculator; use PhpOffice\PhpPresentation\PhpPresentation; @@ -31,9 +29,12 @@ use PhpOffice\PhpPresentation\Shape\RichText; use PhpOffice\PhpPresentation\Shape\Table; use PhpOffice\PhpPresentation\ShapeContainerInterface; +use PhpOffice\PhpPresentation\Traits\ShapeCollection; abstract class AbstractSlide implements ComparableInterface, ShapeContainerInterface { + use ShapeCollection; + /** * @var string */ @@ -44,13 +45,6 @@ abstract class AbstractSlide implements ComparableInterface, ShapeContainerInter */ protected $slideTransition; - /** - * Collection of shapes. - * - * @var array|ArrayObject - */ - protected $shapeCollection = []; - /** * Extent Y. * @@ -107,40 +101,6 @@ abstract class AbstractSlide implements ComparableInterface, ShapeContainerInter */ protected $background; - /** - * Get collection of shapes. - * - * @return array|ArrayObject - */ - public function getShapeCollection() - { - return $this->shapeCollection; - } - - /** - * Get collection of shapes. - * - * @param array|ArrayObject $shapeCollection - * - * @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..e32a4c71b 100644 --- a/src/PhpPresentation/Slide/Animation.php +++ b/src/PhpPresentation/Slide/Animation.php @@ -19,42 +19,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/Iterator.php b/src/PhpPresentation/Slide/Iterator.php index 2b621b7ff..f718728ec 100644 --- a/src/PhpPresentation/Slide/Iterator.php +++ b/src/PhpPresentation/Slide/Iterator.php @@ -21,6 +21,7 @@ use IteratorIterator; use PhpOffice\PhpPresentation\PhpPresentation; +use ReturnTypeWillChange; // @phpstan-ignore-next-line class Iterator extends IteratorIterator @@ -50,7 +51,7 @@ public function __construct(PhpPresentation $subject) /** * Rewind iterator. */ - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function rewind(): void { $this->position = 0; @@ -61,7 +62,7 @@ public function rewind(): void * * @return \PhpOffice\PhpPresentation\Slide */ - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function current() { return $this->subject->getSlide($this->position); @@ -72,7 +73,7 @@ public function current() * * @return int */ - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function key() { return $this->position; @@ -81,7 +82,7 @@ public function key() /** * Next value. */ - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function next(): void { ++$this->position; @@ -92,7 +93,7 @@ public function next(): void * * @return bool */ - #[\ReturnTypeWillChange] + #[ReturnTypeWillChange] public function valid() { return $this->position < $this->subject->getSlideCount(); diff --git a/src/PhpPresentation/Slide/Note.php b/src/PhpPresentation/Slide/Note.php index d60542813..b7a323c67 100644 --- a/src/PhpPresentation/Slide/Note.php +++ b/src/PhpPresentation/Slide/Note.php @@ -19,16 +19,17 @@ namespace PhpOffice\PhpPresentation\Slide; -use ArrayObject; -use PhpOffice\PhpPresentation\AbstractShape; use PhpOffice\PhpPresentation\ComparableInterface; use PhpOffice\PhpPresentation\GeometryCalculator; 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 +37,6 @@ class Note implements ComparableInterface, ShapeContainerInterface */ private $parent; - /** - * Collection of shapes. - * - * @var array|ArrayObject - */ - private $shapeCollection; - /** * Note identifier. * @@ -93,33 +87,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..24c34544b 100644 --- a/src/PhpPresentation/Slide/SlideLayout.php +++ b/src/PhpPresentation/Slide/SlideLayout.php @@ -19,7 +19,6 @@ namespace PhpOffice\PhpPresentation\Slide; -use ArrayObject; use PhpOffice\PhpPresentation\ComparableInterface; use PhpOffice\PhpPresentation\ShapeContainerInterface; use PhpOffice\PhpPresentation\Style\ColorMap; @@ -62,7 +61,7 @@ class SlideLayout extends AbstractSlide implements ComparableInterface, ShapeCon /** * Mapping of colors to the theme. * - * @var \PhpOffice\PhpPresentation\Style\ColorMap + * @var ColorMap */ public $colorMap; @@ -73,8 +72,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..1d30e539a 100644 --- a/src/PhpPresentation/Slide/SlideMaster.php +++ b/src/PhpPresentation/Slide/SlideMaster.php @@ -19,7 +19,6 @@ namespace PhpOffice\PhpPresentation\Slide; -use ArrayObject; use PhpOffice\PhpPresentation\ComparableInterface; use PhpOffice\PhpPresentation\PhpPresentation; use PhpOffice\PhpPresentation\ShapeContainerInterface; @@ -80,8 +79,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/Borders.php b/src/PhpPresentation/Style/Borders.php index efdc2867b..f2aefa5b8 100644 --- a/src/PhpPresentation/Style/Borders.php +++ b/src/PhpPresentation/Style/Borders.php @@ -29,42 +29,42 @@ class Borders implements ComparableInterface /** * Left. * - * @var \PhpOffice\PhpPresentation\Style\Border + * @var Border */ private $left; /** * Right. * - * @var \PhpOffice\PhpPresentation\Style\Border + * @var Border */ private $right; /** * Top. * - * @var \PhpOffice\PhpPresentation\Style\Border + * @var Border */ private $top; /** * Bottom. * - * @var \PhpOffice\PhpPresentation\Style\Border + * @var Border */ private $bottom; /** * Diagonal up. * - * @var \PhpOffice\PhpPresentation\Style\Border + * @var Border */ private $diagonalUp; /** * Diagonal down. * - * @var \PhpOffice\PhpPresentation\Style\Border + * @var Border */ private $diagonalDown; @@ -94,7 +94,7 @@ public function __construct() /** * Get Left. * - * @return \PhpOffice\PhpPresentation\Style\Border + * @return Border */ public function getLeft() { @@ -104,7 +104,7 @@ public function getLeft() /** * Get Right. * - * @return \PhpOffice\PhpPresentation\Style\Border + * @return Border */ public function getRight() { @@ -114,7 +114,7 @@ public function getRight() /** * Get Top. * - * @return \PhpOffice\PhpPresentation\Style\Border + * @return Border */ public function getTop() { @@ -124,7 +124,7 @@ public function getTop() /** * Get Bottom. * - * @return \PhpOffice\PhpPresentation\Style\Border + * @return Border */ public function getBottom() { @@ -134,7 +134,7 @@ public function getBottom() /** * Get Diagonal Up. * - * @return \PhpOffice\PhpPresentation\Style\Border + * @return Border */ public function getDiagonalUp() { @@ -144,7 +144,7 @@ public function getDiagonalUp() /** * Get Diagonal Down. * - * @return \PhpOffice\PhpPresentation\Style\Border + * @return Border */ public function getDiagonalDown() { diff --git a/src/PhpPresentation/Style/Bullet.php b/src/PhpPresentation/Style/Bullet.php index e31a06c55..1222cc1f4 100644 --- a/src/PhpPresentation/Style/Bullet.php +++ b/src/PhpPresentation/Style/Bullet.php @@ -149,7 +149,7 @@ public function getBulletType() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\Style\Bullet + * @return Bullet */ public function setBulletType($pValue = self::TYPE_NONE) { @@ -173,7 +173,7 @@ public function getBulletFont() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\Style\Bullet + * @return Bullet */ public function setBulletFont($pValue = 'Calibri') { @@ -200,7 +200,7 @@ public function getBulletChar() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\Style\Bullet + * @return Bullet */ public function setBulletChar($pValue = '-') { @@ -224,7 +224,7 @@ public function getBulletNumericStyle() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\Style\Bullet + * @return Bullet */ public function setBulletNumericStyle($pValue = self::NUMERIC_DEFAULT) { @@ -248,7 +248,7 @@ public function getBulletNumericStartAt() * * @param int|string $pValue * - * @return \PhpOffice\PhpPresentation\Style\Bullet + * @return Bullet */ public function setBulletNumericStartAt($pValue = 1) { diff --git a/src/PhpPresentation/Style/Color.php b/src/PhpPresentation/Style/Color.php index a10ffdc73..6e1f54da6 100644 --- a/src/PhpPresentation/Style/Color.php +++ b/src/PhpPresentation/Style/Color.php @@ -78,7 +78,7 @@ public function getARGB() * * @param string $pValue * - * @return \PhpOffice\PhpPresentation\Style\Color + * @return Color */ public function setARGB($pValue = self::COLOR_BLACK) { @@ -146,7 +146,7 @@ public function getRGB() * @param string $pValue * @param string $pAlpha * - * @return \PhpOffice\PhpPresentation\Style\Color + * @return Color */ public function setRGB($pValue = '000000', $pAlpha = 'FF') { diff --git a/src/PhpPresentation/Style/Font.php b/src/PhpPresentation/Style/Font.php index 2ba0bca7c..2975df4ef 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'; @@ -47,13 +66,9 @@ class Font implements ComparableInterface public const UNDERLINE_WAVYHEAVY = 'wavyHeavy'; public const UNDERLINE_WORDS = 'words'; - 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 + public const BASELINE_SUPERSCRIPT = 300000; + public const BASELINE_SUBSCRIPT = -250000; /** * Name. @@ -62,6 +77,27 @@ class Font implements ComparableInterface */ private $name = 'Calibri'; + /** + * Panose. + * + * @var string + */ + private $panose = ''; + + /** + * Pitch Family. + * + * @var int + */ + private $pitchFamily = 0; + + /** + * Charset. + * + * @var int + */ + private $charset = self::CHARSET_DEFAULT; + /** * Font Size. * @@ -84,18 +120,11 @@ class Font implements ComparableInterface private $italic = false; /** - * Superscript. - * - * @var bool - */ - private $superScript = false; - - /** - * Subscript. + * Baseline. * - * @var bool + * @var int */ - private $subScript = false; + private $baseline = 0; /** * Capitalization. @@ -114,9 +143,9 @@ class Font implements ComparableInterface /** * Strikethrough. * - * @var bool + * @var string */ - private $strikethrough = false; + private $strikethrough = self::STRIKE_NONE; /** * Foreground color. @@ -172,6 +201,75 @@ public function setName(string $pValue = 'Calibri'): self return $this; } + /** + * Get panose. + */ + public function getPanose(): string + { + return $this->panose; + } + + /** + * Set panose. + */ + public function setPanose(string $pValue): self + { + 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. + */ + public function getPitchFamily(): int + { + return $this->pitchFamily; + } + + /** + * Set pitchFamily. + */ + public function setPitchFamily(int $pValue): self + { + $this->pitchFamily = $pValue; + + return $this; + } + + /** + * Get charset. + */ + public function getCharset(): int + { + return $this->charset; + } + + /** + * Set charset. + */ + public function setCharset(int $pValue): self + { + $this->charset = $pValue; + + return $this; + } + /** * Get Character Spacing. */ @@ -245,44 +343,62 @@ public function setItalic(bool $pValue = false): self return $this; } + /** + * Set Baseline. + */ + public function setBaseline(int $pValue): self + { + $this->baseline = $pValue; + + return $this; + } + + /** + * Get Baseline. + */ + public function getBaseline(): int + { + return $this->baseline; + } + /** * Get SuperScript. + * + * @deprecated getBaseline() === self::BASELINE_SUPERSCRIPT */ public function isSuperScript(): bool { - return $this->superScript; + return $this->getBaseline() === self::BASELINE_SUPERSCRIPT; } /** * Set SuperScript. + * + * @deprecated setBaseline(self::BASELINE_SUPERSCRIPT) */ public function setSuperScript(bool $pValue = false): self { - $this->superScript = $pValue; - - // Set SubScript at false only if SuperScript is true - if (true === $pValue) { - $this->subScript = false; - } - - return $this; + return $this->setBaseline($pValue ? self::BASELINE_SUPERSCRIPT : ($this->getBaseline() == self::BASELINE_SUBSCRIPT ? $this->getBaseline() : 0)); } + /** + * Get SubScript. + * + * @deprecated getBaseline() === self::BASELINE_SUBSCRIPT + */ public function isSubScript(): bool { - return $this->subScript; + return $this->getBaseline() === self::BASELINE_SUBSCRIPT; } + /** + * Set SubScript. + * + * @deprecated setBaseline(self::BASELINE_SUBSCRIPT) + */ public function setSubScript(bool $pValue = false): self { - $this->subScript = $pValue; - - // Set SuperScript at false only if SubScript is true - if (true === $pValue) { - $this->superScript = false; - } - - return $this; + return $this->setBaseline($pValue ? self::BASELINE_SUBSCRIPT : ($this->getBaseline() == self::BASELINE_SUPERSCRIPT ? $this->getBaseline() : 0)); } /** @@ -335,18 +451,43 @@ 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 + * + * @return self */ - public function setStrikethrough(bool $pValue = false): self + public function setStrikethrough($pValue = false) { - $this->strikethrough = $pValue; + 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; + } return $this; } @@ -405,8 +546,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..af3b3e1c3 100644 --- a/src/PhpPresentation/Style/Shadow.php +++ b/src/PhpPresentation/Style/Shadow.php @@ -20,12 +20,17 @@ namespace PhpOffice\PhpPresentation\Style; use PhpOffice\PhpPresentation\ComparableInterface; +use PhpOffice\PhpPresentation\Exception\NotAllowedValueException; /** * \PhpOffice\PhpPresentation\Style\Shadow. */ 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 +86,11 @@ class Shadow implements ComparableInterface */ private $alpha = 50; + /** + * @var string + */ + private $type = self::TYPE_SHADOW_OUTER; + /** * Hash index. * @@ -224,6 +234,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 +266,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..6c7582cb1 --- /dev/null +++ b/src/PhpPresentation/Traits/ShapeCollection.php @@ -0,0 +1,96 @@ + + */ + 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. + * + * @return array + */ + 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. + * + * @param array $shapeCollection + */ + public function setShapeCollection(array $shapeCollection = []): self + { + $this->shapeCollection = $shapeCollection; + + return $this; + } + + /** + * @return static + */ + public function addShape(AbstractShape $shape) + { + $this->shapeCollection[] = $shape; + + return $this; + } + + /** + * @return static + */ + public function unsetShape(int $key) + { + unset($this->shapeCollection[$key]); + + return $this; + } +} diff --git a/src/PhpPresentation/Writer/AbstractDecoratorWriter.php b/src/PhpPresentation/Writer/AbstractDecoratorWriter.php index aab1d0eda..ddcce2a31 100644 --- a/src/PhpPresentation/Writer/AbstractDecoratorWriter.php +++ b/src/PhpPresentation/Writer/AbstractDecoratorWriter.php @@ -28,7 +28,7 @@ abstract class AbstractDecoratorWriter abstract public function render(): ZipInterface; /** - * @var \PhpOffice\PhpPresentation\HashTable + * @var HashTable */ protected $oHashTable; diff --git a/src/PhpPresentation/Writer/AbstractWriter.php b/src/PhpPresentation/Writer/AbstractWriter.php index 3d935c417..edbfb89c8 100644 --- a/src/PhpPresentation/Writer/AbstractWriter.php +++ b/src/PhpPresentation/Writer/AbstractWriter.php @@ -19,7 +19,6 @@ namespace PhpOffice\PhpPresentation\Writer; -use ArrayIterator; use PhpOffice\Common\Adapter\Zip\ZipInterface; use PhpOffice\PhpPresentation\AbstractShape; use PhpOffice\PhpPresentation\HashTable; @@ -116,7 +115,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 +123,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/ODPresentation.php b/src/PhpPresentation/Writer/ODPresentation.php index 5c8432fac..f142fe06c 100644 --- a/src/PhpPresentation/Writer/ODPresentation.php +++ b/src/PhpPresentation/Writer/ODPresentation.php @@ -156,7 +156,7 @@ public function hasDiskCaching() * * @param string $directory Disk caching directory * - * @return \PhpOffice\PhpPresentation\Writer\ODPresentation + * @return ODPresentation */ public function setUseDiskCaching(bool $pValue = false, ?string $directory = null) { diff --git a/src/PhpPresentation/Writer/ODPresentation/Content.php b/src/PhpPresentation/Writer/ODPresentation/Content.php index c12a2fc11..33de96a40 100644 --- a/src/PhpPresentation/Writer/ODPresentation/Content.php +++ b/src/PhpPresentation/Writer/ODPresentation/Content.php @@ -27,7 +27,6 @@ use PhpOffice\PhpPresentation\Shape\Chart; use PhpOffice\PhpPresentation\Shape\Comment; use PhpOffice\PhpPresentation\Shape\Drawing\AbstractDrawingAdapter; -use PhpOffice\PhpPresentation\Shape\Drawing as ShapeDrawing; use PhpOffice\PhpPresentation\Shape\Group; use PhpOffice\PhpPresentation\Shape\Line; use PhpOffice\PhpPresentation\Shape\Media; @@ -448,10 +447,8 @@ protected function writeShapeMedia(XMLWriter $objWriter, Media $shape): void /** * Write picture. - * - * @param AbstractDrawingAdapter $shape */ - protected function writeShapeDrawing(XMLWriter $objWriter, ShapeDrawing\AbstractDrawingAdapter $shape): void + protected function writeShapeDrawing(XMLWriter $objWriter, AbstractDrawingAdapter $shape): void { // draw:frame $objWriter->startElement('draw:frame'); @@ -565,9 +562,9 @@ protected function writeShapeTxt(XMLWriter $objWriter, RichText $shape): void } } $objWriter->endElement(); - //=============================================== - // Bullet list - //=============================================== + //=============================================== + // Bullet list + //=============================================== } elseif ('bullet' == $paragraph->getBulletStyle()->getBulletType()) { $bCstShpHasBullet = true; // Open the bullet list diff --git a/src/PhpPresentation/Writer/ODPresentation/ObjectsChart.php b/src/PhpPresentation/Writer/ODPresentation/ObjectsChart.php index c58b25d60..e2f896c2a 100644 --- a/src/PhpPresentation/Writer/ODPresentation/ObjectsChart.php +++ b/src/PhpPresentation/Writer/ODPresentation/ObjectsChart.php @@ -311,7 +311,7 @@ protected function writeAxisStyle(Chart $chart): void $this->writeGridlineStyle($chart->getPlotArea()->getAxisY()->getMinorGridlines(), 'styleAxisYGridlinesMinor'); } - protected function writeAxisMainStyle(Chart\Axis $axis, string $styleName, AbstractType $chartType): void + protected function writeAxisMainStyle(Axis $axis, string $styleName, AbstractType $chartType): void { // style:style $this->xmlContent->startElement('style:style'); @@ -363,7 +363,7 @@ protected function writeAxisMainStyle(Chart\Axis $axis, string $styleName, Abstr $this->xmlContent->endElement(); } - protected function writeAxisTitleStyle(Chart\Axis $axis, string $styleName): void + protected function writeAxisTitleStyle(Axis $axis, string $styleName): void { // style:style $this->xmlContent->startElement('style:style'); diff --git a/src/PhpPresentation/Writer/PowerPoint2007.php b/src/PhpPresentation/Writer/PowerPoint2007.php index a116ca8a3..dd46c37ee 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007.php +++ b/src/PhpPresentation/Writer/PowerPoint2007.php @@ -147,7 +147,7 @@ public function hasDiskCaching() * * @param string $directory Disk caching directory * - * @return \PhpOffice\PhpPresentation\Writer\PowerPoint2007 + * @return PowerPoint2007 */ public function setUseDiskCaching(bool $useDiskCaching = false, ?string $directory = null) { diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index 5aa7303a7..58ef3b244 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(); } } @@ -172,7 +169,7 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, int $sh if ($shape->isPlaceholder()) { $objWriter->writeAttribute('name', 'Placeholder for ' . $shape->getPlaceholder()->getType()); } else { - $objWriter->writeAttribute('name', ''); + $objWriter->writeAttribute('name', $shape->getName()); } // Hyperlink if ($shape->hasHyperlink()) { @@ -238,10 +235,12 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, int $sh //@link :http://msdn.microsoft.com/en-us/library/documentformat.openxml.drawing.bodyproperties%28v=office.14%29.aspx $objWriter->startElement('a:bodyPr'); if (!$shape->isPlaceholder()) { + // Vertical alignment $verticalAlign = $shape->getActiveParagraph()->getAlignment()->getVertical(); if (Alignment::VERTICAL_BASE != $verticalAlign && Alignment::VERTICAL_AUTO != $verticalAlign) { $objWriter->writeAttribute('anchor', $verticalAlign); } + $objWriter->writeAttribute('anchorCtr', $shape->getVerticalAlignCenter()); if (RichText::WRAP_SQUARE != $shape->getWrap()) { $objWriter->writeAttribute('wrap', $shape->getWrap()); } @@ -255,14 +254,12 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, int $sh if ($shape->isUpright()) { $objWriter->writeAttribute('upright', '1'); } - if ($shape->isVertical()) { - $objWriter->writeAttribute('vert', 'vert'); - } + $objWriter->writeAttribute('vert', $shape->isVertical() ? 'vert' : 'horz'); $objWriter->writeAttribute('bIns', CommonDrawing::pixelsToEmu($shape->getInsetBottom())); $objWriter->writeAttribute('lIns', CommonDrawing::pixelsToEmu($shape->getInsetLeft())); $objWriter->writeAttribute('rIns', CommonDrawing::pixelsToEmu($shape->getInsetRight())); $objWriter->writeAttribute('tIns', CommonDrawing::pixelsToEmu($shape->getInsetTop())); - if (1 != $shape->getColumns()) { + if ($shape->getColumns() != 1) { $objWriter->writeAttribute('numCol', $shape->getColumns()); $objWriter->writeAttribute('spcCol', CommonDrawing::pixelsToEmu($shape->getColumnSpacing())); } @@ -565,7 +562,7 @@ protected function writeParagraphs(XMLWriter $objWriter, array $paragraphs): voi /** * Write Paragraph Styles (a:pPr). */ - protected function writeParagraphStyles(XMLWriter $objWriter, RichText\Paragraph $paragraph, bool $isPlaceholder = false): void + protected function writeParagraphStyles(XMLWriter $objWriter, Paragraph $paragraph, bool $isPlaceholder = false): void { $objWriter->startElement('a:pPr'); $objWriter->writeAttribute('algn', $paragraph->getAlignment()->getHorizontal()); @@ -639,7 +636,7 @@ protected function writeParagraphStyles(XMLWriter $objWriter, RichText\Paragraph /** * Write RichTextElement Styles (a:pPr). */ - protected function writeRunStyles(XMLWriter $objWriter, RichText\Run $element): void + protected function writeRunStyles(XMLWriter $objWriter, Run $element): void { // a:rPr $objWriter->startElement('a:rPr'); @@ -649,7 +646,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', 'sngStrike'); + + // Strikethrough + $objWriter->writeAttribute('strike', $element->getFont()->getStrikethrough()); // Size $objWriter->writeAttribute('sz', ($element->getFont()->getSize() * 100)); @@ -663,9 +662,8 @@ protected function writeRunStyles(XMLWriter $objWriter, RichText\Run $element): // Capitalization $objWriter->writeAttribute('cap', $element->getFont()->getCapitalization()); - // Superscript / subscript - $objWriter->writeAttributeIf($element->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($element->getFont()->isSubScript(), 'baseline', '-250000'); + // Baseline + $objWriter->writeAttributeIf($element->getFont()->getBaseline() !== 0, 'baseline', $element->getFont()->getBaseline()); // Color - a:solidFill $objWriter->startElement('a:solidFill'); @@ -678,6 +676,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() !== '') { + $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 @@ -791,7 +806,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())); 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 63897ee18..d21f6863a 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsCore.php @@ -73,9 +73,14 @@ public function render(): ZipInterface // cp:category $objWriter->writeElement('cp:category', $this->oPresentation->getDocumentProperties()->getCategory()); + // cp:revision + $objWriter->writeElement('cp:revision', $this->oPresentation->getDocumentProperties()->getRevision()); + + // cp:contentStatus 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 358affd6a..aac86bc75 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/DocPropsThumbnail.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/DocPropsThumbnail.php @@ -25,18 +25,15 @@ class DocPropsThumbnail extends AbstractDecoratorWriter { public function render(): ZipInterface { - $pathThumbnail = $this->getPresentation()->getPresentationProperties()->getThumbnailPath(); - - if ($pathThumbnail) { - $fileThumbnail = file_get_contents($pathThumbnail); - $gdImage = imagecreatefromstring($fileThumbnail); + $thumnbail = $this->getPresentation()->getPresentationProperties()->getThumbnail(); + if ($thumnbail) { + $gdImage = imagecreatefromstring($thumnbail); if ($gdImage) { ob_start(); imagejpeg($gdImage); $imageContents = ob_get_contents(); ob_end_clean(); imagedestroy($gdImage); - $this->getZip()->addFromString('docProps/thumbnail.jpeg', $imageContents); } } diff --git a/src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php b/src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php index d2cd90410..f28fb74ad 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 @@ -550,7 +549,6 @@ protected function writePlotArea(XMLWriter $objWriter, PlotArea $subject, Chart * Write Legend. * * @param XMLWriter $objWriter XML Writer - * @param Chart\Legend $subject */ protected function writeLegend(XMLWriter $objWriter, Legend $subject): void { @@ -609,11 +607,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'); @@ -703,7 +700,6 @@ protected function writeLayout(XMLWriter $objWriter, $subject): void * Write Type Area. * * @param XMLWriter $objWriter XML Writer - * @param Chart\Type\Area $subject */ protected function writeTypeArea(XMLWriter $objWriter, Area $subject, bool $includeSheet = false): void { @@ -804,7 +800,6 @@ protected function writeTypeArea(XMLWriter $objWriter, Area $subject, bool $incl * Write Type Bar. * * @param XMLWriter $objWriter XML Writer - * @param Chart\Type\Bar $subject */ protected function writeTypeBar(XMLWriter $objWriter, Bar $subject, bool $includeSheet = false): void { @@ -895,11 +890,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'); @@ -1018,7 +1012,6 @@ protected function writeTypeBar(XMLWriter $objWriter, Bar $subject, bool $includ * Write Type Bar3D. * * @param XMLWriter $objWriter XML Writer - * @param Chart\Type\Bar3D $subject */ protected function writeTypeBar3D(XMLWriter $objWriter, Bar3D $subject, bool $includeSheet = false): void { @@ -1102,11 +1095,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 +1303,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 +1445,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 +1608,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 +1760,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 +1935,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 +2100,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 +2378,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 +2481,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..de600cdf1 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'); } @@ -386,7 +371,7 @@ protected function writeSlide(Slide $pSlide): string $objWriter->endElement(); } - if ($oBackground instanceof Slide\Background\Image) { + if ($oBackground instanceof Image) { // a:blipFill $objWriter->startElement('a:blipFill'); diff --git a/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php b/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php index 58eb325dd..7d652778c 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/Relationships.php @@ -63,17 +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 - if ($this->getPresentation()->getPresentationProperties()->getThumbnailPath()) { - $pathThumbnail = file_get_contents($this->getPresentation()->getPresentationProperties()->getThumbnailPath()); - $gdImage = imagecreatefromstring($pathThumbnail); + + // 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..34acb7d2e 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,14 +98,13 @@ 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) { - 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); - if ($imgTemp instanceof File) { - $imgTemp->setPath($imgPath, false); + foreach ($pPhpPresentation->getSlide($i)->getShapeCollection() as $shape) { + if ($shape instanceof AbstractDrawingAdapter) { + $imgPath = 'zip://' . $pFilename . '#media/' . $shape->getImageIndex() . '/' . pathinfo($shape->getPath(), PATHINFO_BASENAME); + if ($shape instanceof File) { + $shape->setPath($imgPath, false); } else { - $imgTemp->setPath($imgPath); + $shape->setPath($imgPath); } } } 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/Shape/RichTextTest.php b/tests/PhpPresentation/Tests/Shape/RichTextTest.php index 4fd697574..e75137a1e 100644 --- a/tests/PhpPresentation/Tests/Shape/RichTextTest.php +++ b/tests/PhpPresentation/Tests/Shape/RichTextTest.php @@ -277,7 +277,7 @@ public function testHashCode(): void $object = new RichText(); $hash = $object->getActiveParagraph()->getHashCode(); - $hash .= RichText::WRAP_SQUARE . RichText::AUTOFIT_DEFAULT . RichText::OVERFLOW_OVERFLOW . RichText::OVERFLOW_OVERFLOW . '00104.89.69.64.8'; + $hash .= RichText::WRAP_SQUARE . RichText::AUTOFIT_DEFAULT . RichText::OVERFLOW_OVERFLOW . RichText::OVERFLOW_OVERFLOW . '00104.89.69.64.80'; $hash .= md5('00000' . $object->getFill()->getHashCode() . $object->getShadow()->getHashCode() . '' . get_parent_class($object)); $hash .= get_class($object); self::assertEquals(md5($hash), $object->getHashCode()); 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/BorderTest.php b/tests/PhpPresentation/Tests/Style/BorderTest.php index 80b4d3498..279f0b345 100644 --- a/tests/PhpPresentation/Tests/Style/BorderTest.php +++ b/tests/PhpPresentation/Tests/Style/BorderTest.php @@ -51,7 +51,7 @@ public function testSetGetColor(): void $object = new Border(); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Border', $object->setColor()); self::assertNull($object->getColor()); - self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Border', $object->setColor(new Color(COLOR::COLOR_BLUE))); + self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Border', $object->setColor(new Color(Color::COLOR_BLUE))); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Color', $object->getColor()); self::assertEquals('FF0000FF', $object->getColor()->getARGB()); } @@ -66,7 +66,7 @@ public function testSetGetDashStyle(): void self::assertEquals(Border::DASH_SOLID, $object->getDashStyle()); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Border', $object->setDashStyle('')); self::assertEquals(Border::DASH_SOLID, $object->getDashStyle()); - self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Border', $object->setDashStyle(BORDER::DASH_DASH)); + self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Border', $object->setDashStyle(Border::DASH_DASH)); self::assertEquals(Border::DASH_DASH, $object->getDashStyle()); } @@ -91,7 +91,7 @@ public function testSetGetLineStyle(): void self::assertEquals(Border::LINE_SINGLE, $object->getLineStyle()); self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Border', $object->setLineStyle('')); self::assertEquals(Border::LINE_SINGLE, $object->getLineStyle()); - self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Border', $object->setLineStyle(BORDER::LINE_DOUBLE)); + self::assertInstanceOf('PhpOffice\\PhpPresentation\\Style\\Border', $object->setLineStyle(Border::LINE_DOUBLE)); self::assertEquals(Border::LINE_DOUBLE, $object->getLineStyle()); } diff --git a/tests/PhpPresentation/Tests/Style/ColorTest.php b/tests/PhpPresentation/Tests/Style/ColorTest.php index 97485b57d..c4b5055f5 100644 --- a/tests/PhpPresentation/Tests/Style/ColorTest.php +++ b/tests/PhpPresentation/Tests/Style/ColorTest.php @@ -36,7 +36,7 @@ public function testConstruct(): void { $object = new Color(); self::assertEquals(Color::COLOR_BLACK, $object->getARGB()); - $object = new Color(COLOR::COLOR_BLUE); + $object = new Color(Color::COLOR_BLUE); self::assertEquals(Color::COLOR_BLUE, $object->getARGB()); } diff --git a/tests/PhpPresentation/Tests/Style/FillTest.php b/tests/PhpPresentation/Tests/Style/FillTest.php index 3430b430e..676156ed3 100644 --- a/tests/PhpPresentation/Tests/Style/FillTest.php +++ b/tests/PhpPresentation/Tests/Style/FillTest.php @@ -50,9 +50,9 @@ public function testConstruct(): void public function testSetGetEndColor(): void { $object = new Fill(); - self::assertInstanceOf(Fill::class, $object->setEndColor(new Color(COLOR::COLOR_BLUE))); + self::assertInstanceOf(Fill::class, $object->setEndColor(new Color(Color::COLOR_BLUE))); self::assertInstanceOf(Color::class, $object->getEndColor()); - self::assertEquals(COLOR::COLOR_BLUE, $object->getEndColor()->getARGB()); + self::assertEquals(Color::COLOR_BLUE, $object->getEndColor()->getARGB()); } /** @@ -86,9 +86,9 @@ public function testSetGetRotation(): void public function testSetGetStartColor(): void { $object = new Fill(); - self::assertInstanceOf(Fill::class, $object->setStartColor(new Color(COLOR::COLOR_BLUE))); + self::assertInstanceOf(Fill::class, $object->setStartColor(new Color(Color::COLOR_BLUE))); self::assertInstanceOf(Color::class, $object->getStartColor()); - self::assertEquals(COLOR::COLOR_BLUE, $object->getStartColor()->getARGB()); + self::assertEquals(Color::COLOR_BLUE, $object->getStartColor()->getARGB()); } /** diff --git a/tests/PhpPresentation/Tests/Style/FontTest.php b/tests/PhpPresentation/Tests/Style/FontTest.php index 711c2da53..6eabdd74b 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. */ @@ -154,11 +224,11 @@ public function testUnderline(): void { $object = new Font(); self::assertInstanceOf(Font::class, $object->setUnderline()); - self::assertEquals(FONT::UNDERLINE_NONE, $object->getUnderline()); + self::assertEquals(Font::UNDERLINE_NONE, $object->getUnderline()); self::assertInstanceOf(Font::class, $object->setUnderline('')); - self::assertEquals(FONT::UNDERLINE_NONE, $object->getUnderline()); - self::assertInstanceOf(Font::class, $object->setUnderline(FONT::UNDERLINE_DASH)); - self::assertEquals(FONT::UNDERLINE_DASH, $object->getUnderline()); + self::assertEquals(Font::UNDERLINE_NONE, $object->getUnderline()); + self::assertInstanceOf(Font::class, $object->setUnderline(Font::UNDERLINE_DASH)); + self::assertEquals(Font::UNDERLINE_DASH, $object->getUnderline()); } /** @@ -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..67181ac06 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 = []; $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 */ diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 8d83f9d83..b674b39bd 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -51,4 +51,4 @@ }); require_once __DIR__ . '/../src/PhpPresentation/Autoloader.php'; -\PhpOffice\PhpPresentation\Autoloader::register(); +PhpOffice\PhpPresentation\Autoloader::register(); diff --git a/tests/resources/files/serialized.phppt b/tests/resources/files/serialized.phppt index 828ad826e..8c213110f 100644 Binary files a/tests/resources/files/serialized.phppt and b/tests/resources/files/serialized.phppt differ