From 21b20d2383cb5725ce1dc1766d96b417324ac5b8 Mon Sep 17 00:00:00 2001 From: Quentin Machard Date: Fri, 19 May 2017 11:49:08 +0200 Subject: [PATCH] PowerPoint2007 Writer: Enable style and position of a Placeholder * Create SlideLayout Sample * When write a Placeholder, fetch the first element of the first paragraph to apply style > > Co-authored-by: Quentin Machard Co-authored-by: Progi1984 --- composer.json | 4 +- docs/changes/1.1.0.md | 1 + samples/Sample_19_SlideMaster.php | 8 +- samples/Sample_20_SlideLayout.php | 73 +++++ ...lSlide.php => Sample_22_ExternalSlide.php} | 0 .../Writer/PowerPoint2007/AbstractSlide.php | 305 ++++++++++-------- .../Writer/PowerPoint2007/PptSlidesTest.php | 92 ++++++ 7 files changed, 345 insertions(+), 138 deletions(-) create mode 100644 samples/Sample_20_SlideLayout.php rename samples/{Sample_20_ExternalSlide.php => Sample_22_ExternalSlide.php} (100%) diff --git a/composer.json b/composer.json index 60cd20f7e..be83206bc 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,9 @@ "php samples/Sample_17_Comment.php", "php samples/Sample_18_Animation.php", "php samples/Sample_19_SlideMaster.php", - "php samples/Sample_20_ExternalSlide.php" + "php samples/Sample_20_SlideLayout.php", + "php samples/Sample_21_AutoShape.php", + "php samples/Sample_22_ExternalSlide.php" ] } } diff --git a/docs/changes/1.1.0.md b/docs/changes/1.1.0.md index 40b49b0db..80fb2f5bb 100644 --- a/docs/changes/1.1.0.md +++ b/docs/changes/1.1.0.md @@ -16,6 +16,7 @@ - ODPresentation Writer - 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) ## Improvements - Slide : Raised max value for identifier rand call - [@Scheissy](https://github.com/Scheissy) in [#777](https://github.com/PHPOffice/PHPPresentation/pull/777) diff --git a/samples/Sample_19_SlideMaster.php b/samples/Sample_19_SlideMaster.php index d72b2488b..9f851ac8e 100644 --- a/samples/Sample_19_SlideMaster.php +++ b/samples/Sample_19_SlideMaster.php @@ -55,7 +55,7 @@ ->setVertical(Alignment::VERTICAL_BASE); $shape->setAutoFit(RichText::AUTOFIT_NORMAL); $textRun = $shape->createTextRun('01-02-2000')->getFont()->setSize(18); -$shape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_DATETIME))->getPlaceholder()->setIdx(10); +$shape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_DATETIME)); // Footer placeholder $shape = $oMasterSlide->createRichTextShape(); $shape->setWidthAndHeight(468, 38)->setOffsetX(246)->setOffsetY(680); @@ -64,7 +64,7 @@ ->setVertical(Alignment::VERTICAL_BASE); $shape->setAutoFit(RichText::AUTOFIT_NORMAL); $textRun = $shape->createTextRun('Placeholder for Footer')->getFont()->setSize(18); -$shape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_FOOTER))->getPlaceholder()->setIdx(11); +$shape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_FOOTER)); // Slidenumber placeholder $shape = $oMasterSlide->createRichTextShape(); $shape->setWidthAndHeight(140, 38)->setOffsetX(770)->setOffsetY(680); @@ -72,8 +72,8 @@ ->setHorizontal(Alignment::HORIZONTAL_RIGHT) ->setVertical(Alignment::VERTICAL_BASE); $shape->setAutoFit(RichText::AUTOFIT_NORMAL); -$textRun = $shape->createTextRun('')->getFont()->setSize(18); -$shape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_SLIDENUM))->getPlaceholder()->setIdx(12); +$textRun = $shape->createTextRun('')->getFont()->setSize(10); +$shape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_SLIDENUM)); // Create a shape (drawing) echo date('H:i:s') . ' Create a shape (drawing)' . EOL; diff --git a/samples/Sample_20_SlideLayout.php b/samples/Sample_20_SlideLayout.php new file mode 100644 index 000000000..1e18ac5b3 --- /dev/null +++ b/samples/Sample_20_SlideLayout.php @@ -0,0 +1,73 @@ +getDocumentProperties()->setCreator('PHPOffice') + ->setLastModifiedBy('PHPPresentation Team') + ->setTitle('Sample 20 SlideLayout') + ->setSubject('Sample 20 Subject') + ->setDescription('Sample 20 Description') + ->setKeywords('office 2007 openxml libreoffice odt php') + ->setCategory('Sample Category'); + +// Create slide +echo date('H:i:s') . ' Create slide' . EOL; +$currentSlide = $objPHPPresentation->getActiveSlide(); + +echo date('H:i:s') . ' Create SlideLayout' . EOL; +$slideLayout = $objPHPPresentation->getAllMasterSlides()[0]->createSlideLayout(); +$slideLayout->setLayoutName('Sample Layout'); + +echo date('H:i:s') . ' Create Footer' . EOL; +$footerTextShape = $slideLayout->createRichTextShape(); +$footerTextShape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_FOOTER)); + +$footerTextShape + ->setOffsetX(77) + ->setOffsetY(677) + ->setWidth(448) + ->setHeight(23); + +$footerTextRun = $footerTextShape->createTextRun('Footer placeholder'); +$footerTextRun->getFont() + ->setName('Calibri') + ->setSize(9) + ->setColor(new Color(Color::COLOR_DARKGREEN)) + ->setBold(true); + +echo date('H:i:s') . ' Create SlideNumber' . EOL; + +$numberTextShape = $slideLayout->createRichTextShape(); +$numberTextShape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_SLIDENUM)); + +$numberTextShape + ->setOffsetX(43) + ->setOffsetY(677) + ->setWidth(43) + ->setHeight(23); + +$numberTextRun = $numberTextShape->createTextRun(''); +$numberTextRun->getFont() + ->setName('Calibri') + ->setSize(9) + ->setColor(new Color(Color::COLOR_DARKGREEN)) + ->setBold(true); + +echo date('H:i:s') . ' Apply Layout' . EOL; +$currentSlide->setSlideLayout($slideLayout); + +// Save file +echo write($objPHPPresentation, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/samples/Sample_20_ExternalSlide.php b/samples/Sample_22_ExternalSlide.php similarity index 100% rename from samples/Sample_20_ExternalSlide.php rename to samples/Sample_22_ExternalSlide.php diff --git a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php index 45a4a35af..5aa7303a7 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php @@ -180,11 +180,11 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, int $sh } // > p:sp\p:nvSpPr $objWriter->endElement(); - // p:sp\p:cNvSpPr + // p:sp\p:nvSpPr\p:cNvSpPr $objWriter->startElement('p:cNvSpPr'); $objWriter->writeAttribute('txBox', '1'); $objWriter->endElement(); - // p:sp\p:cNvSpPr\p:nvPr + // p:sp\p:nvSpPr\p:nvPr if ($shape->isPlaceholder()) { $objWriter->startElement('p:nvPr'); $objWriter->startElement('p:ph'); @@ -197,36 +197,35 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, int $sh } else { $objWriter->writeElement('p:nvPr', null); } - // > p:sp\p:cNvSpPr + // > p:sp\p:nvSpPr $objWriter->endElement(); // p:sp\p:spPr $objWriter->startElement('p:spPr'); - if (!$shape->isPlaceholder()) { - // p:sp\p:spPr\a:xfrm - $objWriter->startElement('a:xfrm'); - $objWriter->writeAttributeIf(0 != $shape->getRotation(), 'rot', CommonDrawing::degreesToAngle((int) $shape->getRotation())); - // p:sp\p:spPr\a:xfrm\a:off - $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX())); - $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY())); - $objWriter->endElement(); - // p:sp\p:spPr\a:xfrm\a:ext - $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth())); - $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight())); - $objWriter->endElement(); - // > p:sp\p:spPr\a:xfrm - $objWriter->endElement(); - // p:sp\p:spPr\a:prstGeom - $objWriter->startElement('a:prstGeom'); - $objWriter->writeAttribute('prst', 'rect'); + // p:sp\p:spPr\a:xfrm + $objWriter->startElement('a:xfrm'); + $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation())); + // p:sp\p:spPr\a:xfrm\a:off + $objWriter->startElement('a:off'); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY())); + $objWriter->endElement(); + // p:sp\p:spPr\a:xfrm\a:ext + $objWriter->startElement('a:ext'); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight())); + $objWriter->endElement(); + // > p:sp\p:spPr\a:xfrm + $objWriter->endElement(); + // p:sp\p:spPr\a:prstGeom + $objWriter->startElement('a:prstGeom'); + $objWriter->writeAttribute('prst', 'rect'); - // p:sp\p:spPr\a:prstGeom\a:avLst - $objWriter->writeElement('a:avLst'); + // p:sp\p:spPr\a:prstGeom\a:avLst + $objWriter->writeElement('a:avLst'); + + $objWriter->endElement(); - $objWriter->endElement(); - } $this->writeFill($objWriter, $shape->getFill()); $this->writeBorder($objWriter, $shape->getBorder(), ''); $this->writeShadow($objWriter, $shape->getShadow()); @@ -287,11 +286,30 @@ protected function writeShapeText(XMLWriter $objWriter, RichText $shape, int $sh Placeholder::PH_TYPE_DATETIME == $shape->getPlaceholder()->getType()) ) { $objWriter->startElement('a:p'); + + // Paragraph Style + $paragraphs = $shape->getParagraphs(); + if (!empty($paragraphs)) { + $paragraph = &$paragraphs[0]; + $this->writeParagraphStyles($objWriter, $paragraph, true); + } + $objWriter->startElement('a:fld'); $objWriter->writeAttribute('id', $this->getGUID()); $objWriter->writeAttribute('type', ( Placeholder::PH_TYPE_SLIDENUM == $shape->getPlaceholder()->getType() ? 'slidenum' : 'datetime' )); + + if (isset($paragraph)) { + $elements = $paragraph->getRichTextElements(); + if (!empty($elements)) { + $element = &$elements[0]; + if ($element instanceof Run) { + $this->writeRunStyles($objWriter, $element); + } + } + } + $objWriter->writeElement('a:t', ( Placeholder::PH_TYPE_SLIDENUM == $shape->getPlaceholder()->getType() ? '' : '03-04-05' )); @@ -506,7 +524,7 @@ protected function writeShapeTable(XMLWriter $objWriter, ShapeTable $shape, int * @param XMLWriter $objWriter XML Writer * @param array $paragraphs */ - protected function writeParagraphs(XMLWriter $objWriter, array $paragraphs, bool $bIsPlaceholder = false): void + protected function writeParagraphs(XMLWriter $objWriter, array $paragraphs): void { // Loop trough paragraphs foreach ($paragraphs as $paragraph) { @@ -514,76 +532,7 @@ protected function writeParagraphs(XMLWriter $objWriter, array $paragraphs, bool $objWriter->startElement('a:p'); // a:pPr - if (!$bIsPlaceholder) { - // a:pPr - $objWriter->startElement('a:pPr'); - $objWriter->writeAttribute('algn', $paragraph->getAlignment()->getHorizontal()); - $objWriter->writeAttribute('rtl', $paragraph->getAlignment()->isRTL() ? '1' : '0'); - $objWriter->writeAttribute('fontAlgn', $paragraph->getAlignment()->getVertical()); - $objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginLeft())); - $objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginRight())); - $objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getIndent())); - $objWriter->writeAttribute('lvl', $paragraph->getAlignment()->getLevel()); - - // a:pPr:a:lnSpc - $objWriter->startElement('a:lnSpc'); - if ($paragraph->getLineSpacingMode() == Paragraph::LINE_SPACING_MODE_POINT) { - $objWriter->startElement('a:spcPts'); - $objWriter->writeAttribute('val', $paragraph->getLineSpacing() * 100); - $objWriter->endElement(); - } else { - $objWriter->startElement('a:spcPct'); - $objWriter->writeAttribute('val', $paragraph->getLineSpacing() * 1000); - $objWriter->endElement(); - } - // >a:pPr:a:lnSpc - $objWriter->endElement(); - - $objWriter->startElement('a:spcBef'); - $objWriter->startElement('a:spcPts'); - $objWriter->writeAttribute('val', $paragraph->getSpacingBefore() * 100); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('a:spcAft'); - $objWriter->startElement('a:spcPts'); - $objWriter->writeAttribute('val', $paragraph->getSpacingAfter() * 100); - $objWriter->endElement(); - $objWriter->endElement(); - - // Bullet type specified? - if (Bullet::TYPE_NONE != $paragraph->getBulletStyle()->getBulletType()) { - // Color - // a:buClr must be before a:buFont (else PowerPoint crashes at launch) - if ($paragraph->getBulletStyle()->getBulletColor() instanceof Color) { - $objWriter->startElement('a:buClr'); - $this->writeColor($objWriter, $paragraph->getBulletStyle()->getBulletColor()); - $objWriter->endElement(); - } - - // a:buFont - $objWriter->startElement('a:buFont'); - $objWriter->writeAttribute('typeface', $paragraph->getBulletStyle()->getBulletFont()); - $objWriter->endElement(); - - if (Bullet::TYPE_BULLET == $paragraph->getBulletStyle()->getBulletType()) { - // a:buChar - $objWriter->startElement('a:buChar'); - $objWriter->writeAttribute('char', $paragraph->getBulletStyle()->getBulletChar()); - $objWriter->endElement(); - } elseif (Bullet::TYPE_NUMERIC == $paragraph->getBulletStyle()->getBulletType()) { - // a:buAutoNum - $objWriter->startElement('a:buAutoNum'); - $objWriter->writeAttribute('type', $paragraph->getBulletStyle()->getBulletNumericStyle()); - if (1 != $paragraph->getBulletStyle()->getBulletNumericStartAt()) { - $objWriter->writeAttribute('startAt', $paragraph->getBulletStyle()->getBulletNumericStartAt()); - } - $objWriter->endElement(); - } - } - - $objWriter->endElement(); - } + $this->writeParagraphStyles($objWriter, $paragraph, false); // Loop trough rich text elements $elements = $paragraph->getRichTextElements(); @@ -596,38 +545,8 @@ protected function writeParagraphs(XMLWriter $objWriter, array $paragraphs, bool $objWriter->startElement('a:r'); // a:rPr - if ($element instanceof Run && !$bIsPlaceholder) { - // a:rPr - $objWriter->startElement('a:rPr'); - - // Lang - $objWriter->writeAttribute('lang', ($element->getLanguage() ? $element->getLanguage() : 'en-US')); - $objWriter->writeAttributeIf($element->getFont()->isBold(), 'b', '1'); - $objWriter->writeAttributeIf($element->getFont()->isItalic(), 'i', '1'); - $objWriter->writeAttributeIf($element->getFont()->isStrikethrough(), 'strike', 'sngStrike'); - $objWriter->writeAttribute('sz', ($element->getFont()->getSize() * 100)); - $objWriter->writeAttribute('spc', $element->getFont()->getCharacterSpacing()); - $objWriter->writeAttribute('u', $element->getFont()->getUnderline()); - $objWriter->writeAttribute('cap', $element->getFont()->getCapitalization()); - $objWriter->writeAttributeIf($element->getFont()->isSuperScript(), 'baseline', '300000'); - $objWriter->writeAttributeIf($element->getFont()->isSubScript(), 'baseline', '-250000'); - // Color - a:solidFill - $objWriter->startElement('a:solidFill'); - $this->writeColor($objWriter, $element->getFont()->getColor()); - $objWriter->endElement(); - - // Font - // - a:latin - // - a:ea - // - a:cs - $objWriter->startElement('a:' . $element->getFont()->getFormat()); - $objWriter->writeAttribute('typeface', $element->getFont()->getName()); - $objWriter->endElement(); - - // a:hlinkClick - $this->writeHyperlink($objWriter, $element); - - $objWriter->endElement(); + if ($element instanceof Run) { + $this->writeRunStyles($objWriter, $element); } // t @@ -643,6 +562,130 @@ protected function writeParagraphs(XMLWriter $objWriter, array $paragraphs, bool } } + /** + * Write Paragraph Styles (a:pPr). + */ + protected function writeParagraphStyles(XMLWriter $objWriter, RichText\Paragraph $paragraph, bool $isPlaceholder = false): void + { + $objWriter->startElement('a:pPr'); + $objWriter->writeAttribute('algn', $paragraph->getAlignment()->getHorizontal()); + $objWriter->writeAttribute('rtl', $paragraph->getAlignment()->isRTL() ? '1' : '0'); + $objWriter->writeAttribute('fontAlgn', $paragraph->getAlignment()->getVertical()); + $objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginLeft())); + $objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginRight())); + $objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getIndent())); + $objWriter->writeAttribute('lvl', $paragraph->getAlignment()->getLevel()); + + $objWriter->startElement('a:lnSpc'); + if ($paragraph->getLineSpacingMode() == Paragraph::LINE_SPACING_MODE_POINT) { + $objWriter->startElement('a:spcPts'); + $objWriter->writeAttribute('val', $paragraph->getLineSpacing() * 100); + $objWriter->endElement(); + } else { + $objWriter->startElement('a:spcPct'); + $objWriter->writeAttribute('val', $paragraph->getLineSpacing() * 1000); + $objWriter->endElement(); + } + $objWriter->endElement(); + + $objWriter->startElement('a:spcBef'); + $objWriter->startElement('a:spcPts'); + $objWriter->writeAttribute('val', $paragraph->getSpacingBefore() * 100); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('a:spcAft'); + $objWriter->startElement('a:spcPts'); + $objWriter->writeAttribute('val', $paragraph->getSpacingAfter() * 100); + $objWriter->endElement(); + $objWriter->endElement(); + + if (!$isPlaceholder) { + // Bullet type specified? + if ($paragraph->getBulletStyle()->getBulletType() != Bullet::TYPE_NONE) { + // Color + // a:buClr must be before a:buFont (else PowerPoint crashes at launch) + if ($paragraph->getBulletStyle()->getBulletColor() instanceof Color) { + $objWriter->startElement('a:buClr'); + $this->writeColor($objWriter, $paragraph->getBulletStyle()->getBulletColor()); + $objWriter->endElement(); + } + + // a:buFont + $objWriter->startElement('a:buFont'); + $objWriter->writeAttribute('typeface', $paragraph->getBulletStyle()->getBulletFont()); + $objWriter->endElement(); + + if ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_BULLET) { + // a:buChar + $objWriter->startElement('a:buChar'); + $objWriter->writeAttribute('char', $paragraph->getBulletStyle()->getBulletChar()); + $objWriter->endElement(); + } elseif ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_NUMERIC) { + // a:buAutoNum + $objWriter->startElement('a:buAutoNum'); + $objWriter->writeAttribute('type', $paragraph->getBulletStyle()->getBulletNumericStyle()); + if ($paragraph->getBulletStyle()->getBulletNumericStartAt() != 1) { + $objWriter->writeAttribute('startAt', $paragraph->getBulletStyle()->getBulletNumericStartAt()); + } + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + } + + /** + * Write RichTextElement Styles (a:pPr). + */ + protected function writeRunStyles(XMLWriter $objWriter, RichText\Run $element): void + { + // a:rPr + $objWriter->startElement('a:rPr'); + + // Lang + $objWriter->writeAttribute('lang', ($element->getLanguage() ? $element->getLanguage() : 'en-US')); + + $objWriter->writeAttributeIf($element->getFont()->isBold(), 'b', '1'); + $objWriter->writeAttributeIf($element->getFont()->isItalic(), 'i', '1'); + $objWriter->writeAttributeIf($element->getFont()->isStrikethrough(), 'strike', 'sngStrike'); + + // Size + $objWriter->writeAttribute('sz', ($element->getFont()->getSize() * 100)); + + // Character spacing + $objWriter->writeAttribute('spc', $element->getFont()->getCharacterSpacing()); + + // Underline + $objWriter->writeAttribute('u', $element->getFont()->getUnderline()); + + // Capitalization + $objWriter->writeAttribute('cap', $element->getFont()->getCapitalization()); + + // Superscript / subscript + $objWriter->writeAttributeIf($element->getFont()->isSuperScript(), 'baseline', '300000'); + $objWriter->writeAttributeIf($element->getFont()->isSubScript(), 'baseline', '-250000'); + + // Color - a:solidFill + $objWriter->startElement('a:solidFill'); + $this->writeColor($objWriter, $element->getFont()->getColor()); + $objWriter->endElement(); + + // Font + // - a:latin + // - a:ea + // - a:cs + $objWriter->startElement('a:' . $element->getFont()->getFormat()); + $objWriter->writeAttribute('typeface', $element->getFont()->getName()); + $objWriter->endElement(); + + // a:hlinkClick + $this->writeHyperlink($objWriter, $element); + + $objWriter->endElement(); + } + /** * Write Line Shape. * @@ -740,10 +783,6 @@ protected function writeShapeLine(XMLWriter $objWriter, Line $shape, int $shapeI */ protected function writeShadow(XMLWriter $objWriter, Shadow $oShadow): void { - if (!($oShadow instanceof Shadow)) { - return; - } - if (!$oShadow->isVisible()) { return; } diff --git a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlidesTest.php b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlidesTest.php index 2548bb9c3..9e0640477 100644 --- a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlidesTest.php +++ b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptSlidesTest.php @@ -24,6 +24,7 @@ use PhpOffice\PhpPresentation\Shape\Comment; use PhpOffice\PhpPresentation\Shape\Group; use PhpOffice\PhpPresentation\Shape\Media; +use PhpOffice\PhpPresentation\Shape\Placeholder; use PhpOffice\PhpPresentation\Shape\RichText; use PhpOffice\PhpPresentation\Shape\RichText\Paragraph; use PhpOffice\PhpPresentation\Slide\Animation; @@ -737,6 +738,97 @@ public function testParagraphSpacingBefore(): void $this->assertIsSchemaECMA376Valid(); } + public function testPlaceHolder(): void + { + $expectedType = Placeholder::PH_TYPE_SLIDENUM; + $expectedX = mt_rand(1, 100); + $expectedY = mt_rand(1, 100); + $expectedW = mt_rand(1, 100); + $expectedH = mt_rand(1, 100); + + $oSlide = $this->oPresentation->getActiveSlide(); + $oRichText = $oSlide->createRichTextShape(); + $oRichText + ->setPlaceHolder(new Placeholder($expectedType)) + ->setOffsetX($expectedX) + ->setOffsetY($expectedY) + ->setWidth($expectedW) + ->setHeight($expectedH); + $oRichText->createTextRun('Test'); + + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:nvSpPr/p:cNvPr'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'name', 'Placeholder for sldNum'); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:nvSpPr/p:nvPr/p:ph'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'type', $expectedType); + $this->assertZipXmlAttributeNotExists('ppt/slides/slide1.xml', $element, 'idx'); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:xfrm/a:off'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'x', Drawing::pixelsToEmu($expectedX)); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'y', Drawing::pixelsToEmu($expectedY)); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:xfrm/a:ext'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'cx', Drawing::pixelsToEmu($expectedW)); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'cy', Drawing::pixelsToEmu($expectedH)); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:pPr'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:fld'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'type', 'slidenum'); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:fld/a:rPr'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:fld/a:t'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlElementEquals('ppt/slides/slide1.xml', $element, ''); + } + + public function testPlaceHolderWithIdx(): void + { + $expectedType = Placeholder::PH_TYPE_DATETIME; + $expectedIdx = 1; + $expectedX = mt_rand(1, 100); + $expectedY = mt_rand(1, 100); + $expectedW = mt_rand(1, 100); + $expectedH = mt_rand(1, 100); + + $oSlide = $this->oPresentation->getActiveSlide(); + $oRichText = $oSlide->createRichTextShape(); + $oRichText + ->setPlaceHolder((new Placeholder($expectedType))->setIdx($expectedIdx)) + ->setOffsetX($expectedX) + ->setOffsetY($expectedY) + ->setWidth($expectedW) + ->setHeight($expectedH); + $oRichText->createTextRun('Test'); + + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:nvSpPr/p:cNvPr'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'name', 'Placeholder for dt'); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:nvSpPr/p:nvPr/p:ph'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'type', $expectedType); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'idx', $expectedIdx); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:xfrm/a:off'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'x', Drawing::pixelsToEmu($expectedX)); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'y', Drawing::pixelsToEmu($expectedY)); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:xfrm/a:ext'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'cx', Drawing::pixelsToEmu($expectedW)); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'cy', Drawing::pixelsToEmu($expectedH)); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:pPr'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:fld'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlAttributeEquals('ppt/slides/slide1.xml', $element, 'type', 'datetime'); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:fld/a:rPr'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:fld/a:t'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $this->assertZipXmlElementEquals('ppt/slides/slide1.xml', $element, '03-04-05'); + } + public function testRichTextAutoFitNormal(): void { $expectedFontScale = 47.5;