/** * Save PhpPresentation to file * * @param string $pFilename * @throws \Exception */ public function save($pFilename) { if (empty($pFilename)) { throw new \Exception("Filename is empty."); } if (!is_null($this->presentation)) { // Create new ZIP file and open it for writing $objZip = new \ZipArchive(); // Try opening the ZIP file if ($objZip->open($pFilename, \ZipArchive::CREATE) !== true) { if ($objZip->open($pFilename, \ZipArchive::OVERWRITE) !== true) { throw new \Exception("Could not open " . $pFilename . " for writing."); } } // Add media $slideCount = $this->presentation->getSlideCount(); for ($i = 0; $i < $slideCount; ++$i) { for ($j = 0; $j < $this->presentation->getSlide($i)->getShapeCollection()->count(); ++$j) { if ($this->presentation->getSlide($i)->getShapeCollection()->offsetGet($j) instanceof AbstractDrawing) { $imgTemp = $this->presentation->getSlide($i)->getShapeCollection()->offsetGet($j); $objZip->addFromString('media/' . $imgTemp->getFilename(), file_get_contents($imgTemp->getPath())); } } } // Add PhpPresentation.xml to the document, which represents a PHP serialized PhpPresentation object $objZip->addFromString('PhpPresentation.xml', $this->writeSerialized($this->presentation, $pFilename)); // Close file if ($objZip->close() === false) { throw new \Exception("Could not close zip file {$pFilename}."); } } else { throw new \Exception("PhpPresentation object unassigned."); } }
/** * Read Slide * * @param \DOMElement $nodeSlide */ protected function loadSlide(\DOMElement $nodeSlide) { // Core $this->oPhpPresentation->createSlide(); $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1); if ($nodeSlide->hasAttribute('draw:name')) { $this->oPhpPresentation->getActiveSlide()->setName($nodeSlide->getAttribute('draw:name')); } if ($nodeSlide->hasAttribute('draw:style-name')) { $keyStyle = $nodeSlide->getAttribute('draw:style-name'); if (isset($this->arrayStyles[$keyStyle])) { $this->oPhpPresentation->getActiveSlide()->setBackground($this->arrayStyles[$keyStyle]['background']); } } foreach ($this->oXMLReader->getElements('draw:frame', $nodeSlide) as $oNodeFrame) { if ($this->oXMLReader->getElement('draw:image', $oNodeFrame)) { $this->loadShapeDrawing($oNodeFrame); continue; } if ($this->oXMLReader->getElement('draw:text-box', $oNodeFrame)) { $this->loadShapeRichText($oNodeFrame); continue; } } return true; }
/** * Get an array of all drawings * * @param PhpPresentation $pPhpPresentation * @return \PhpOffice\PhpPresentation\Shape\AbstractDrawing[] All drawings in PhpPresentation * @throws \Exception */ public function allDrawings(PhpPresentation $pPhpPresentation) { // Get an array of all drawings $aDrawings = array(); // Loop trough PhpPresentation $slideCount = $pPhpPresentation->getSlideCount(); for ($i = 0; $i < $slideCount; ++$i) { // Loop trough images and add to array $iterator = $pPhpPresentation->getSlide($i)->getShapeCollection()->getIterator(); while ($iterator->valid()) { if ($iterator->current() instanceof AbstractDrawing && !$iterator->current() instanceof Table) { $aDrawings[] = $iterator->current(); } elseif ($iterator->current() instanceof Group) { $iterator2 = $iterator->current()->getShapeCollection()->getIterator(); while ($iterator2->valid()) { if ($iterator2->current() instanceof AbstractDrawing && !$iterator2->current() instanceof Table) { $aDrawings[] = $iterator2->current(); } $iterator2->next(); } } $iterator->next(); } } return $aDrawings; }
/** * Test add external slide */ public function testAddExternalSlide() { $origin = new PhpPresentation(); $slide = $origin->getSlide(); $object = new PhpPresentation(); $object->addExternalSlide($slide); $this->assertEquals(2, $object->getSlideCount()); }
/** * Extract data from slide * @param \DOMElement $nodeSlide */ protected function loadSlide(\DOMElement $nodeSlide) { // Core $this->oPhpPresentation->createSlide(); $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1); foreach ($this->oXMLReader->getElements('draw:frame', $nodeSlide) as $oNodeFrame) { if ($this->oXMLReader->getElement('draw:image', $oNodeFrame)) { $this->loadShapeDrawing($oNodeFrame); continue; } if ($this->oXMLReader->getElement('draw:text-box', $oNodeFrame)) { $this->loadShapeRichText($oNodeFrame); continue; } } return true; }
/** * Extract data from slide * @param string $sPart * @param string $baseFile */ protected function loadSlide($sPart, $baseFile) { $xmlReader = new XMLReader(); if ($xmlReader->getDomFromString($sPart)) { // Core $this->oPhpPresentation->createSlide(); $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1); foreach ($xmlReader->getElements('/p:sld/p:cSld/p:spTree/*') as $oNode) { switch ($oNode->tagName) { case 'p:pic': $this->loadShapeDrawing($xmlReader, $oNode, $baseFile); break; case 'p:sp': $this->loadShapeRichText($xmlReader, $oNode, $baseFile); break; default: //var_export($oNode->tagName); } } } }
protected function displayPhpPresentationInfo(PhpPresentation $oPHPPpt) { $this->append('<div class="infoBlk" id="divPhpPresentationInfo">'); $this->append('<dl>'); $this->append('<dt>Number of slides</dt><dd>' . $oPHPPpt->getSlideCount() . '</dd>'); $this->append('<dt>Document Layout Name</dt><dd>' . (empty($oPHPPpt->getLayout()->getDocumentLayout()) ? 'Custom' : $oPHPPpt->getLayout()->getDocumentLayout()) . '</dd>'); $this->append('<dt>Document Layout Height</dt><dd>' . $oPHPPpt->getLayout()->getCY(DocumentLayout::UNIT_MILLIMETER) . ' mm</dd>'); $this->append('<dt>Document Layout Width</dt><dd>' . $oPHPPpt->getLayout()->getCX(DocumentLayout::UNIT_MILLIMETER) . ' mm</dd>'); $this->append('<dt>Properties : Category</dt><dd>' . $oPHPPpt->getDocumentProperties()->getCategory() . '</dd>'); $this->append('<dt>Properties : Company</dt><dd>' . $oPHPPpt->getDocumentProperties()->getCompany() . '</dd>'); $this->append('<dt>Properties : Created</dt><dd>' . $oPHPPpt->getDocumentProperties()->getCreated() . '</dd>'); $this->append('<dt>Properties : Creator</dt><dd>' . $oPHPPpt->getDocumentProperties()->getCreator() . '</dd>'); $this->append('<dt>Properties : Description</dt><dd>' . $oPHPPpt->getDocumentProperties()->getDescription() . '</dd>'); $this->append('<dt>Properties : Keywords</dt><dd>' . $oPHPPpt->getDocumentProperties()->getKeywords() . '</dd>'); $this->append('<dt>Properties : Last Modified By</dt><dd>' . $oPHPPpt->getDocumentProperties()->getLastModifiedBy() . '</dd>'); $this->append('<dt>Properties : Modified</dt><dd>' . $oPHPPpt->getDocumentProperties()->getModified() . '</dd>'); $this->append('<dt>Properties : Subject</dt><dd>' . $oPHPPpt->getDocumentProperties()->getSubject() . '</dd>'); $this->append('<dt>Properties : Title</dt><dd>' . $oPHPPpt->getDocumentProperties()->getTitle() . '</dd>'); $this->append('</dl>'); $this->append('</div>'); foreach ($oPHPPpt->getAllSlides() as $oSlide) { $this->append('<div class="infoBlk" id="div' . $oSlide->getHashCode() . 'Info">'); $this->append('<dl>'); $this->append('<dt>HashCode</dt><dd>' . $oSlide->getHashCode() . '</dd>'); $this->append('<dt>Slide Layout</dt><dd>Layout::' . $this->getConstantName('\\PhpOffice\\PhpPresentation\\Slide\\Layout', $oSlide->getSlideLayout()) . '</dd>'); $this->append('<dt>Offset X</dt><dd>' . $oSlide->getOffsetX() . '</dd>'); $this->append('<dt>Offset Y</dt><dd>' . $oSlide->getOffsetY() . '</dd>'); $this->append('<dt>Extent X</dt><dd>' . $oSlide->getExtentX() . '</dd>'); $this->append('<dt>Extent Y</dt><dd>' . $oSlide->getExtentY() . '</dd>'); $oBkg = $oSlide->getBackground(); if ($oBkg instanceof Slide\AbstractBackground) { if ($oBkg instanceof Slide\Background\Color) { $this->append('<dt>Background Color</dt><dd>#' . $oBkg->getColor()->getRGB() . '</dd>'); } if ($oBkg instanceof Slide\Background\Image) { $sBkgImgContents = file_get_contents($oBkg->getPath()); $this->append('<dt>Background Image</dt><dd><img src="data:image/png;base64,' . base64_encode($sBkgImgContents) . '"></dd>'); } } $this->append('</dl>'); $this->append('</div>'); foreach ($oSlide->getShapeCollection() as $oShape) { if ($oShape instanceof Group) { foreach ($oShape->getShapeCollection() as $oShapeChild) { $this->displayShapeInfo($oShapeChild); } } else { $this->displayShapeInfo($oShape); } } } }
/** * A container record that specifies a presentation slide or title master slide. * @param string $stream * @param int $pos * @link http://msdn.microsoft.com/en-us/library/dd946323(v=office.12).aspx */ private function readRecordSlideContainer($stream, $pos) { // Core $this->oPhpPresentation->createSlide(); $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1); // *** slideAtom (32 bytes) $slideAtom = $this->readRecordSlideAtom($stream, $pos); if ($slideAtom['length'] == 0) { throw new \Exception('PowerPoint97 Reader : record SlideAtom'); } $pos += $slideAtom['length']; // *** slideShowSlideInfoAtom (24 bytes) $slideShowInfoAtom = $this->readRecordSlideShowSlideInfoAtom($stream, $pos); $pos += $slideShowInfoAtom['length']; // *** perSlideHFContainer (variable) : optional $perSlideHFContainer = $this->readRecordPerSlideHeadersFootersContainer($stream, $pos); $pos += $perSlideHFContainer['length']; // *** rtSlideSyncInfo12 (variable) : optional $rtSlideSyncInfo12 = $this->readRecordRoundTripSlideSyncInfo12Container($stream, $pos); $pos += $rtSlideSyncInfo12['length']; // *** drawing (variable) $drawing = $this->readRecordDrawingContainer($stream, $pos); $pos += $drawing['length']; // *** slideSchemeColorSchemeAtom (40 bytes) $slideSchemeColorAtom = $this->readRecordSlideSchemeColorSchemeAtom($stream, $pos); if ($slideSchemeColorAtom['length'] == 0) { throw new \Exception('PowerPoint97 Reader : record SlideSchemeColorSchemeAtom'); } $pos += $slideSchemeColorAtom['length']; // *** slideNameAtom (variable) $slideNameAtom = $this->readRecordSlideNameAtom($stream, $pos); $pos += $slideNameAtom['length']; // *** slideProgTagsContainer (variable). $slideProgTags = $this->readRecordSlideProgTagsContainer($stream, $pos); $pos += $slideProgTags['length']; // *** rgRoundTripSlide (variable) }
/** * Write presentation relationships to XML format * * @param PhpPresentation $pPhpPresentation * @return string XML Output * @throws \Exception */ public function writePresentationRelationships(PhpPresentation $pPhpPresentation) { // Create XML writer $objWriter = $this->getXMLWriter(); // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); // Relation id $relationId = 1; $parentWriter = $this->getParentWriter(); if ($parentWriter instanceof PowerPoint2007) { // Add slide masters $masterSlides = $parentWriter->getLayoutPack()->getMasterSlides(); foreach ($masterSlides as $masterSlide) { // Relationship slideMasters/slideMasterX.xml $this->writeRelationship($objWriter, $relationId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster', 'slideMasters/slideMaster' . $masterSlide['masterid'] . '.xml'); } } // Add slide theme (only one!) // Relationship theme/theme1.xml $this->writeRelationship($objWriter, $relationId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', 'theme/theme1.xml'); // Relationships with slides $slideCount = $pPhpPresentation->getSlideCount(); for ($i = 0; $i < $slideCount; ++$i) { $this->writeRelationship($objWriter, $relationId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slides/slide' . ($i + 1) . '.xml'); } $this->writeRelationship($objWriter, $relationId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps', 'presProps.xml'); $this->writeRelationship($objWriter, $relationId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps', 'viewProps.xml'); $this->writeRelationship($objWriter, $relationId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles', 'tableStyles.xml'); $objWriter->endElement(); // Return return $objWriter->getData(); }
/** * Write docProps/app.xml to XML format * * @param PhpPresentation $pPhpPresentation * @return string XML Output * @throws \Exception */ public function writeDocPropsApp(PhpPresentation $pPhpPresentation) { // Create XML writer $objWriter = $this->getXMLWriter(); // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Properties $objWriter->startElement('Properties'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties'); $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); // Application $objWriter->writeElement('Application', 'Microsoft Office PowerPoint'); // Slides $objWriter->writeElement('Slides', $pPhpPresentation->getSlideCount()); // ScaleCrop $objWriter->writeElement('ScaleCrop', 'false'); // HeadingPairs $objWriter->startElement('HeadingPairs'); // Vector $objWriter->startElement('vt:vector'); $objWriter->writeAttribute('size', '4'); $objWriter->writeAttribute('baseType', 'variant'); // Variant $objWriter->startElement('vt:variant'); $objWriter->writeElement('vt:lpstr', 'Theme'); $objWriter->endElement(); // Variant $objWriter->startElement('vt:variant'); $objWriter->writeElement('vt:i4', '1'); $objWriter->endElement(); // Variant $objWriter->startElement('vt:variant'); $objWriter->writeElement('vt:lpstr', 'Slide Titles'); $objWriter->endElement(); // Variant $objWriter->startElement('vt:variant'); $objWriter->writeElement('vt:i4', '1'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); // TitlesOfParts $objWriter->startElement('TitlesOfParts'); // Vector $objWriter->startElement('vt:vector'); $objWriter->writeAttribute('size', '1'); $objWriter->writeAttribute('baseType', 'lpstr'); $objWriter->writeElement('vt:lpstr', 'Office Theme'); $objWriter->endElement(); $objWriter->endElement(); // Company $objWriter->writeElement('Company', $pPhpPresentation->getProperties()->getCompany()); // LinksUpToDate $objWriter->writeElement('LinksUpToDate', 'false'); // SharedDoc $objWriter->writeElement('SharedDoc', 'false'); // HyperlinksChanged $objWriter->writeElement('HyperlinksChanged', 'false'); // AppVersion $objWriter->writeElement('AppVersion', '12.0000'); $objWriter->endElement(); // Return return $objWriter->getData(); }
/** * Write content types to XML format * * @param PhpPresentation $pPhpPresentation * @return string XML Output * @throws \Exception */ public function writeContentTypes(PhpPresentation $pPhpPresentation) { $parentWriter = $this->getParentWriter(); if (!$parentWriter instanceof PowerPoint2007) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPresentation\\Writer\\PowerPoint2007'); } // Create XML writer $objWriter = $this->getXMLWriter(); // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Types $objWriter->startElement('Types'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types'); // Rels $this->writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml'); // XML $this->writeDefaultContentType($objWriter, 'xml', 'application/xml'); // Themes $masterSlides = $parentWriter->getLayoutPack()->getMasterSlides(); foreach ($masterSlides as $masterSlide) { $this->writeOverrideContentType($objWriter, '/ppt/theme/theme' . $masterSlide['masterid'] . '.xml', 'application/vnd.openxmlformats-officedocument.theme+xml'); } // Presentation $this->writeOverrideContentType($objWriter, '/ppt/presentation.xml', 'application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml'); // PptProps $this->writeOverrideContentType($objWriter, '/ppt/presProps.xml', 'application/vnd.openxmlformats-officedocument.presentationml.presProps+xml'); $this->writeOverrideContentType($objWriter, '/ppt/tableStyles.xml', 'application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml'); $this->writeOverrideContentType($objWriter, '/ppt/viewProps.xml', 'application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml'); // DocProps $this->writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml'); $this->writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml'); $this->writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml'); // Slide masters $masterSlides = $parentWriter->getLayoutPack()->getMasterSlides(); foreach ($masterSlides as $masterSlide) { $this->writeOverrideContentType($objWriter, '/ppt/slideMasters/slideMaster' . $masterSlide['masterid'] . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml'); } // Slide layouts $slideLayouts = $parentWriter->getLayoutPack()->getLayouts(); $numSlideLayouts = count($slideLayouts); for ($i = 0; $i < $numSlideLayouts; ++$i) { $this->writeOverrideContentType($objWriter, '/ppt/slideLayouts/slideLayout' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml'); } // Slides $slideCount = $pPhpPresentation->getSlideCount(); for ($i = 0; $i < $slideCount; ++$i) { $this->writeOverrideContentType($objWriter, '/ppt/slides/slide' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml'); if ($pPhpPresentation->getSlide($i)->getNote()->getShapeCollection()->count() > 0) { $this->writeOverrideContentType($objWriter, '/ppt/notesSlides/notesSlide' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml'); } } // Add layoutpack content types $otherRelations = $parentWriter->getLayoutPack()->getMasterSlideRelations(); foreach ($otherRelations as $otherRelation) { if (strpos($otherRelation['target'], 'http://') !== 0 && $otherRelation['contentType'] != '') { $this->writeOverrideContentType($objWriter, '/ppt/slideMasters/' . $otherRelation['target'], $otherRelation['contentType']); } } $otherRelations = $parentWriter->getLayoutPack()->getThemeRelations(); foreach ($otherRelations as $otherRelation) { if (strpos($otherRelation['target'], 'http://') !== 0 && $otherRelation['contentType'] != '') { $this->writeOverrideContentType($objWriter, '/ppt/theme/' . $otherRelation['target'], $otherRelation['contentType']); } } $otherRelations = $parentWriter->getLayoutPack()->getLayoutRelations(); foreach ($otherRelations as $otherRelation) { if (strpos($otherRelation['target'], 'http://') !== 0 && $otherRelation['contentType'] != '') { $this->writeOverrideContentType($objWriter, '/ppt/slideLayouts/' . $otherRelation['target'], $otherRelation['contentType']); } } // Add media content-types $aMediaContentTypes = array(); // GIF, JPEG, PNG $aMediaContentTypes['gif'] = 'image/gif'; $aMediaContentTypes['jpg'] = 'image/jpeg'; $aMediaContentTypes['jpeg'] = 'image/jpeg'; $aMediaContentTypes['png'] = 'image/png'; foreach ($aMediaContentTypes as $key => $value) { $this->writeDefaultContentType($objWriter, $key, $value); } // XLSX $this->writeDefaultContentType($objWriter, 'xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); // Other media content types $mediaCount = $parentWriter->getDrawingHashTable()->count(); for ($i = 0; $i < $mediaCount; ++$i) { $extension = ''; $mimeType = ''; $shapeIndex = $parentWriter->getDrawingHashTable()->getByIndex($i); if ($shapeIndex instanceof ShapeChart) { // Chart content type $this->writeOverrideContentType($objWriter, '/ppt/charts/chart' . $shapeIndex->getImageIndex() . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); } else { if ($shapeIndex instanceof ShapeDrawing) { $extension = strtolower($shapeIndex->getExtension()); $mimeType = $this->getImageMimeType($shapeIndex->getPath()); } elseif ($shapeIndex instanceof MemoryDrawing) { $extension = strtolower($shapeIndex->getMimeType()); $extension = explode('/', $extension); $extension = $extension[1]; $mimeType = $shapeIndex->getMimeType(); } if (!isset($aMediaContentTypes[$extension])) { $aMediaContentTypes[$extension] = $mimeType; $this->writeDefaultContentType($objWriter, $extension, $mimeType); } } } $objWriter->endElement(); // Return return $objWriter->getData(); }
/** * Write content file to XML format * * @param PhpPresentation $pPhpPresentation * @return string XML Output * @throws \Exception */ public function writePart(PhpPresentation $pPhpPresentation) { // Create XML writer $objWriter = $this->getXMLWriter(); // XML header $objWriter->startDocument('1.0', 'UTF-8'); // office:document-content $objWriter->startElement('office:document-content'); $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0'); $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0'); $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0'); $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0'); $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0'); $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'); $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0'); $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0'); $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0'); $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0'); $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0'); $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML'); $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0'); $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0'); $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer'); $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc'); $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events'); $objWriter->writeAttribute('xmlns:xforms', 'http://www.w3.org/2002/xforms'); $objWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema'); $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $objWriter->writeAttribute('xmlns:smil', 'urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0'); $objWriter->writeAttribute('xmlns:anim', 'urn:oasis:names:tc:opendocument:xmlns:animation:1.0'); $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report'); $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2'); $objWriter->writeAttribute('xmlns:rdfa', 'http://docs.oasis-open.org/opendocument/meta/rdfa#'); $objWriter->writeAttribute('xmlns:field', 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0'); $objWriter->writeAttribute('office:version', '1.2'); // office:automatic-styles $objWriter->startElement('office:automatic-styles'); $this->shapeId = 0; $incSlide = 0; foreach ($pPhpPresentation->getAllSlides() as $pSlide) { // Slides $this->writeStyleSlide($objWriter, $pSlide, $incSlide); // Images $shapes = $pSlide->getShapeCollection(); foreach ($shapes as $shape) { // Increment $this->shapeId ++$this->shapeId; // Check type if ($shape instanceof RichText) { $this->writeTxtStyle($objWriter, $shape); } if ($shape instanceof AbstractDrawing) { $this->writeDrawingStyle($objWriter, $shape); } if ($shape instanceof Line) { $this->writeLineStyle($objWriter, $shape); } if ($shape instanceof Table) { $this->writeTableStyle($objWriter, $shape); } if ($shape instanceof Group) { $this->writeGroupStyle($objWriter, $shape); } } $incSlide++; } // Style : Bullet if (!empty($this->arrStyleBullet)) { foreach ($this->arrStyleBullet as $key => $item) { $oStyle = $item['oStyle']; $arrLevel = explode(';', $item['level']); // style:style $objWriter->startElement('text:list-style'); $objWriter->writeAttribute('style:name', 'L_' . $key); foreach ($arrLevel as $level) { if ($level != '') { $oAlign = $item['oAlign_' . $level]; // text:list-level-style-bullet $objWriter->startElement('text:list-level-style-bullet'); $objWriter->writeAttribute('text:level', $level + 1); $objWriter->writeAttribute('text:bullet-char', $oStyle->getBulletChar()); // style:list-level-properties $objWriter->startElement('style:list-level-properties'); if ($oAlign->getIndent() < 0) { $objWriter->writeAttribute('text:space-before', CommonDrawing::pixelsToCentimeters($oAlign->getMarginLeft() - -1 * $oAlign->getIndent()) . 'cm'); $objWriter->writeAttribute('text:min-label-width', CommonDrawing::pixelsToCentimeters(-1 * $oAlign->getIndent()) . 'cm'); } else { $objWriter->writeAttribute('text:space-before', CommonDrawing::pixelsToCentimeters($oAlign->getMarginLeft() - $oAlign->getIndent()) . 'cm'); $objWriter->writeAttribute('text:min-label-width', CommonDrawing::pixelsToCentimeters($oAlign->getIndent()) . 'cm'); } $objWriter->endElement(); // style:text-properties $objWriter->startElement('style:text-properties'); $objWriter->writeAttribute('fo:font-family', $oStyle->getBulletFont()); $objWriter->writeAttribute('style:font-family-generic', 'swiss'); $objWriter->writeAttribute('style:use-window-font-color', 'true'); $objWriter->writeAttribute('fo:font-size', '100'); $objWriter->endElement(); $objWriter->endElement(); } } $objWriter->endElement(); } } // Style : Paragraph if (!empty($this->arrStyleParagraph)) { foreach ($this->arrStyleParagraph as $key => $item) { // style:style $objWriter->startElement('style:style'); $objWriter->writeAttribute('style:name', 'P_' . $key); $objWriter->writeAttribute('style:family', 'paragraph'); // style:paragraph-properties $objWriter->startElement('style:paragraph-properties'); switch ($item->getAlignment()->getHorizontal()) { case Alignment::HORIZONTAL_LEFT: $objWriter->writeAttribute('fo:text-align', 'left'); break; case Alignment::HORIZONTAL_RIGHT: $objWriter->writeAttribute('fo:text-align', 'right'); break; case Alignment::HORIZONTAL_CENTER: $objWriter->writeAttribute('fo:text-align', 'center'); break; case Alignment::HORIZONTAL_JUSTIFY: $objWriter->writeAttribute('fo:text-align', 'justify'); break; case Alignment::HORIZONTAL_DISTRIBUTED: $objWriter->writeAttribute('fo:text-align', 'justify'); break; default: $objWriter->writeAttribute('fo:text-align', 'left'); break; } $objWriter->endElement(); $objWriter->endElement(); } } // Style : Text : Font if (!empty($this->arrStyleTextFont)) { foreach ($this->arrStyleTextFont as $key => $item) { // style:style $objWriter->startElement('style:style'); $objWriter->writeAttribute('style:name', 'T_' . $key); $objWriter->writeAttribute('style:family', 'text'); // style:text-properties $objWriter->startElement('style:text-properties'); $objWriter->writeAttribute('fo:color', '#' . $item->getColor()->getRGB()); $objWriter->writeAttribute('fo:font-family', $item->getName()); $objWriter->writeAttribute('fo:font-size', $item->getSize() . 'pt'); // @todo : fo:font-style if ($item->isBold()) { $objWriter->writeAttribute('fo:font-weight', 'bold'); } // @todo : style:text-underline-style $objWriter->endElement(); $objWriter->endElement(); } } $objWriter->endElement(); //=============================================== // Body //=============================================== // office:body $objWriter->startElement('office:body'); // office:presentation $objWriter->startElement('office:presentation'); // Write slides $slideCount = $pPhpPresentation->getSlideCount(); $this->shapeId = 0; for ($i = 0; $i < $slideCount; ++$i) { $pSlide = $pPhpPresentation->getSlide($i); $objWriter->startElement('draw:page'); $name = $pSlide->getName(); if (!is_null($name)) { $objWriter->writeAttribute('draw:name', $name); } $objWriter->writeAttribute('draw:master-page-name', 'Standard'); $objWriter->writeAttribute('draw:style-name', 'stylePage' . $i); // Images $shapes = $pSlide->getShapeCollection(); foreach ($shapes as $shape) { // Increment $this->shapeId ++$this->shapeId; // Check type if ($shape instanceof RichText) { $this->writeShapeTxt($objWriter, $shape); } elseif ($shape instanceof Table) { $this->writeShapeTable($objWriter, $shape); } elseif ($shape instanceof Line) { $this->writeShapeLine($objWriter, $shape); } elseif ($shape instanceof Chart) { $this->writeShapeChart($objWriter, $shape); } elseif ($shape instanceof AbstractDrawing) { $this->writeShapePic($objWriter, $shape); } elseif ($shape instanceof Group) { $this->writeShapeGroup($objWriter, $shape); } } // Slide Note if ($pSlide->getNote() instanceof Note) { $this->writeSlideNote($objWriter, $pSlide->getNote()); } $objWriter->endElement(); } if ($pPhpPresentation->getPresentationProperties()->isLoopContinuouslyUntilEsc()) { $objWriter->startElement('presentation:settings'); $objWriter->writeAttribute('presentation:endless', 'true'); $objWriter->writeAttribute('presentation:pause', 'P0s'); $objWriter->writeAttribute('presentation:mouse-visible', 'false'); $objWriter->endElement(); } // > office:presentation $objWriter->endElement(); // > office:body $objWriter->endElement(); // > office:document-content $objWriter->endElement(); // Return return $objWriter->getData(); }
/** * Extract data from slide * @param string $sPart * @param string $baseFile */ protected function loadSlide($sPart, $baseFile) { $xmlReader = new XMLReader(); if ($xmlReader->getDomFromString($sPart)) { // Core $oSlide = $this->oPhpPresentation->createSlide(); $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1); $oSlide->setRelsIndex('ppt/slides/_rels/' . $baseFile . '.rels'); // Background $oElement = $xmlReader->getElement('/p:sld/p:cSld/p:bg/p:bgPr'); if ($oElement) { $oElementColor = $xmlReader->getElement('a:solidFill/a:srgbClr', $oElement); if ($oElementColor) { // Color $oColor = new Color(); $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null); // Background $oBackground = new \PhpOffice\PhpPresentation\Slide\Background\Color(); $oBackground->setColor($oColor); // Slide Background $oSlide = $this->oPhpPresentation->getActiveSlide(); $oSlide->setBackground($oBackground); } $oElementImage = $xmlReader->getElement('a:blipFill/a:blip', $oElement); if ($oElementImage) { $relImg = $this->arrayRels['ppt/slides/_rels/' . $baseFile . '.rels'][$oElementImage->getAttribute('r:embed')]; if (is_array($relImg)) { // File $pathImage = 'ppt/slides/' . $relImg['Target']; $pathImage = explode('/', $pathImage); foreach ($pathImage as $key => $partPath) { if ($partPath == '..') { unset($pathImage[$key - 1]); unset($pathImage[$key]); } } $pathImage = implode('/', $pathImage); $contentImg = $this->oZip->getFromName($pathImage); $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderPpt2007Bkg'); file_put_contents($tmpBkgImg, $contentImg); // Background $oBackground = new Image(); $oBackground->setPath($tmpBkgImg); // Slide Background $oSlide = $this->oPhpPresentation->getActiveSlide(); $oSlide->setBackground($oBackground); } } } // Shapes foreach ($xmlReader->getElements('/p:sld/p:cSld/p:spTree/*') as $oNode) { switch ($oNode->tagName) { case 'p:pic': $this->loadShapeDrawing($xmlReader, $oNode, $oSlide); break; case 'p:sp': $this->loadShapeRichText($xmlReader, $oNode, $oSlide); break; default: //var_export($oNode->tagName); } } // Layout $oSlide = $this->oPhpPresentation->getActiveSlide(); foreach ($this->arrayRels['ppt/slides/_rels/' . $baseFile . '.rels'] as $valueRel) { if ($valueRel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout') { $layoutBasename = basename($valueRel['Target']); if (array_key_exists($layoutBasename, $this->arraySlideLayouts)) { $oSlide->setSlideLayout($this->arraySlideLayouts[$layoutBasename]); } break; } } } }
/** * Write slides * * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param PhpPresentation $pPhpPresentation * @param int $startRelationId * @throws \Exception */ private function writeSlides(XMLWriter $objWriter, PhpPresentation $pPhpPresentation, $startRelationId = 2) { // Write slides $slideCount = $pPhpPresentation->getSlideCount(); for ($i = 0; $i < $slideCount; ++$i) { // p:sldId $this->writeSlide($objWriter, $i + 256, $i + $startRelationId); } }
/** * Save PhpPresentation to file * * @param string $pFilename * @throws \Exception */ public function save($pFilename) { if (empty($pFilename)) { throw new \Exception("Filename is empty"); } if (!is_null($this->presentation)) { // If $pFilename is php://output or php://stdout, make it a temporary file... $originalFilename = $pFilename; if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') { $pFilename = @tempnam('./', 'phppttmp'); if ($pFilename == '') { $pFilename = $originalFilename; } } $wPartDrawing = $this->getWriterPart('Drawing'); if (!$wPartDrawing instanceof Drawing) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPresentation\\Writer\\PowerPoint2007\\Drawing'); } $wPartContentTypes = $this->getWriterPart('ContentTypes'); if (!$wPartContentTypes instanceof ContentTypes) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPresentation\\Writer\\PowerPoint2007\\ContentTypes'); } $wPartRels = $this->getWriterPart('Rels'); if (!$wPartRels instanceof Rels) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPresentation\\Writer\\PowerPoint2007\\Rels'); } $wPartDocProps = $this->getWriterPart('DocProps'); if (!$wPartDocProps instanceof DocProps) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPresentation\\Writer\\PowerPoint2007\\DocProps'); } $wPartTheme = $this->getWriterPart('Theme'); if (!$wPartTheme instanceof Theme) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPresentation\\Writer\\PowerPoint2007\\Theme'); } $wPartPresentation = $this->getWriterPart('Presentation'); if (!$wPartPresentation instanceof Presentation) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPresentation\\Writer\\PowerPoint2007\\Presentation'); } $wPartSlide = $this->getWriterPart('Slide'); if (!$wPartSlide instanceof Slide) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPresentation\\Writer\\PowerPoint2007\\Slide'); } $wPartChart = $this->getWriterPart('Chart'); if (!$wPartChart instanceof Chart) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPresentation\\Writer\\PowerPoint2007\\Chart'); } $wPptProps = $this->getWriterPart('PptProps'); if (!$wPptProps instanceof PptProps) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPresentation\\Writer\\PowerPoint2007\\PptProps'); } // Create drawing dictionary $this->drawingHashTable->addFromSource($wPartDrawing->allDrawings($this->presentation)); // Create new ZIP file and open it for writing $objZip = new \ZipArchive(); // Try opening the ZIP file if ($objZip->open($pFilename, \ZipArchive::OVERWRITE) !== true) { if ($objZip->open($pFilename, \ZipArchive::CREATE) !== true) { throw new \Exception("Could not open " . $pFilename . " for writing."); } } // Add [Content_Types].xml to ZIP file $objZip->addFromString('[Content_Types].xml', $wPartContentTypes->writeContentTypes($this->presentation)); // Add PPT properties and styles to ZIP file - Required for Apple Keynote compatibility. $objZip->addFromString('ppt/presProps.xml', $wPptProps->writePresProps($this->presentation)); $objZip->addFromString('ppt/tableStyles.xml', $wPptProps->writeTableStyles()); $objZip->addFromString('ppt/viewProps.xml', $wPptProps->writeViewProps($this->presentation)); // Add relationships to ZIP file $objZip->addFromString('_rels/.rels', $wPartRels->writeRelationships()); $objZip->addFromString('ppt/_rels/presentation.xml.rels', $wPartRels->writePresentationRelationships($this->presentation)); // Add document properties to ZIP file $objZip->addFromString('docProps/app.xml', $wPartDocProps->writeDocPropsApp($this->presentation)); $objZip->addFromString('docProps/core.xml', $wPartDocProps->writeDocPropsCore($this->presentation)); $objZip->addFromString('docProps/custom.xml', $wPartDocProps->writeDocPropsCustom($this->presentation)); $masterSlides = $this->getLayoutPack()->getMasterSlides(); foreach ($masterSlides as $masterSlide) { // Add themes to ZIP file $objZip->addFromString('ppt/theme/_rels/theme' . $masterSlide['masterid'] . '.xml.rels', $wPartRels->writeThemeRelationships($masterSlide['masterid'])); $objZip->addFromString('ppt/theme/theme' . $masterSlide['masterid'] . '.xml', $wPartTheme->writeTheme($masterSlide['masterid'])); // Add slide masters to ZIP file $objZip->addFromString('ppt/slideMasters/_rels/slideMaster' . $masterSlide['masterid'] . '.xml.rels', $wPartRels->writeSlideMasterRelationships($masterSlide['masterid'])); $objZip->addFromString('ppt/slideMasters/slideMaster' . $masterSlide['masterid'] . '.xml', $masterSlide['body']); } // Add slide layouts to ZIP file $slideLayouts = $this->getLayoutPack()->getLayouts(); foreach ($slideLayouts as $key => $layout) { $objZip->addFromString('ppt/slideLayouts/_rels/slideLayout' . $key . '.xml.rels', $wPartRels->writeSlideLayoutRelationships($key, $layout['masterid'])); $objZip->addFromString('ppt/slideLayouts/slideLayout' . $key . '.xml', utf8_encode($layout['body'])); } // Add layoutpack relations $otherRelations = $this->getLayoutPack()->getMasterSlideRelations(); foreach ($otherRelations as $otherRelation) { if (strpos($otherRelation['target'], 'http://') !== 0) { $objZip->addFromString($this->absoluteZipPath('ppt/slideMasters/' . $otherRelation['target']), $otherRelation['contents']); } } $otherRelations = $this->getLayoutPack()->getThemeRelations(); foreach ($otherRelations as $otherRelation) { if (strpos($otherRelation['target'], 'http://') !== 0) { $objZip->addFromString($this->absoluteZipPath('ppt/theme/' . $otherRelation['target']), $otherRelation['contents']); } } $otherRelations = $this->getLayoutPack()->getLayoutRelations(); foreach ($otherRelations as $otherRelation) { if (strpos($otherRelation['target'], 'http://') !== 0) { $objZip->addFromString($this->absoluteZipPath('ppt/slideLayouts/' . $otherRelation['target']), $otherRelation['contents']); } } // Add presentation to ZIP file $objZip->addFromString('ppt/presentation.xml', $wPartPresentation->writePresentation($this->presentation)); // Add slides (drawings, ...) and slide relationships (drawings, ...) for ($i = 0; $i < $this->presentation->getSlideCount(); ++$i) { $oSlide = $this->presentation->getSlide($i); // Add slide $objZip->addFromString('ppt/slides/_rels/slide' . ($i + 1) . '.xml.rels', $wPartRels->writeSlideRelationships($oSlide)); $objZip->addFromString('ppt/slides/slide' . ($i + 1) . '.xml', $wPartSlide->writeSlide($oSlide)); // Add note slide if ($oSlide->getNote()->getShapeCollection()->count() > 0) { $objZip->addFromString('ppt/notesSlides/notesSlide' . ($i + 1) . '.xml', $wPartSlide->writeNote($oSlide->getNote())); } // Add background image slide $oBkgImage = $oSlide->getBackground(); if ($oBkgImage instanceof Image) { $objZip->addFromString('ppt/media/' . $oBkgImage->getIndexedFilename($i), file_get_contents($oBkgImage->getPath())); } } // Add media for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) { $shape = $this->getDrawingHashTable()->getByIndex($i); if ($shape instanceof DrawingShape) { $imagePath = $shape->getPath(); if (strpos($imagePath, 'zip://') !== false) { $imagePath = substr($imagePath, 6); $imagePathSplitted = explode('#', $imagePath); $imageZip = new \ZipArchive(); $imageZip->open($imagePathSplitted[0]); $imageContents = $imageZip->getFromName($imagePathSplitted[1]); $imageZip->close(); unset($imageZip); } else { $imageContents = file_get_contents($imagePath); } $objZip->addFromString('ppt/media/' . str_replace(' ', '_', $shape->getIndexedFilename()), $imageContents); } elseif ($shape instanceof MemoryDrawingShape) { ob_start(); call_user_func($shape->getRenderingFunction(), $shape->getImageResource()); $imageContents = ob_get_contents(); ob_end_clean(); $objZip->addFromString('ppt/media/' . str_replace(' ', '_', $shape->getIndexedFilename()), $imageContents); } elseif ($shape instanceof ChartShape) { $objZip->addFromString('ppt/charts/' . $shape->getIndexedFilename(), $wPartChart->writeChart($shape)); // Chart relations? if ($shape->hasIncludedSpreadsheet()) { $objZip->addFromString('ppt/charts/_rels/' . $shape->getIndexedFilename() . '.rels', $wPartRels->writeChartRelationships($shape)); $objZip->addFromString('ppt/embeddings/' . $shape->getIndexedFilename() . '.xlsx', $wPartChart->writeSpreadsheet($this->presentation, $shape, $pFilename . '.xlsx')); } } } // Close file if ($objZip->close() === false) { throw new \Exception("Could not close zip file {$pFilename}."); } // If a temporary file was used, copy it to the correct file stream if ($originalFilename != $pFilename) { if (copy($pFilename, $originalFilename) === false) { throw new \Exception("Could not copy temporary zip file {$pFilename} to {$originalFilename}."); } if (@unlink($pFilename) === false) { throw new \Exception('The file ' . $pFilename . ' could not be removed.'); } } } else { throw new \Exception("PhpPresentation object unassigned."); } }
protected function displayPhpPresentationInfo(PhpPresentation $oPHPPpt) { $this->append('<div class="infoBlk" id="divPhpPresentationInfo">'); $this->append('<dl>'); $this->append('<dt>Number of slides</dt><dd>' . $oPHPPpt->getSlideCount() . '</dd>'); $this->append('<dt>Document Layout Height</dt><dd>' . $oPHPPpt->getLayout()->getCY(DocumentLayout::UNIT_MILLIMETER) . ' mm</dd>'); $this->append('<dt>Document Layout Width</dt><dd>' . $oPHPPpt->getLayout()->getCX(DocumentLayout::UNIT_MILLIMETER) . ' mm</dd>'); $this->append('<dt>Properties : Category</dt><dd>' . $oPHPPpt->getProperties()->getCategory() . '</dd>'); $this->append('<dt>Properties : Company</dt><dd>' . $oPHPPpt->getProperties()->getCompany() . '</dd>'); $this->append('<dt>Properties : Created</dt><dd>' . $oPHPPpt->getProperties()->getCreated() . '</dd>'); $this->append('<dt>Properties : Creator</dt><dd>' . $oPHPPpt->getProperties()->getCreator() . '</dd>'); $this->append('<dt>Properties : Description</dt><dd>' . $oPHPPpt->getProperties()->getDescription() . '</dd>'); $this->append('<dt>Properties : Keywords</dt><dd>' . $oPHPPpt->getProperties()->getKeywords() . '</dd>'); $this->append('<dt>Properties : Last Modified By</dt><dd>' . $oPHPPpt->getProperties()->getLastModifiedBy() . '</dd>'); $this->append('<dt>Properties : Modified</dt><dd>' . $oPHPPpt->getProperties()->getModified() . '</dd>'); $this->append('<dt>Properties : Subject</dt><dd>' . $oPHPPpt->getProperties()->getSubject() . '</dd>'); $this->append('<dt>Properties : Title</dt><dd>' . $oPHPPpt->getProperties()->getTitle() . '</dd>'); $this->append('</dl>'); $this->append('</div>'); foreach ($oPHPPpt->getAllSlides() as $oSlide) { $this->append('<div class="infoBlk" id="div' . $oSlide->getHashCode() . 'Info">'); $this->append('<dl>'); $this->append('<dt>HashCode</dt><dd>' . $oSlide->getHashCode() . '</dd>'); $this->append('<dt>Slide Layout</dt><dd>Layout::' . $this->getConstantName('\\PhpOffice\\PhpPresentation\\Slide\\Layout', $oSlide->getSlideLayout()) . '</dd>'); $this->append('<dt>Offset X</dt><dd>' . $oSlide->getOffsetX() . '</dd>'); $this->append('<dt>Offset Y</dt><dd>' . $oSlide->getOffsetY() . '</dd>'); $this->append('<dt>Extent X</dt><dd>' . $oSlide->getExtentX() . '</dd>'); $this->append('<dt>Extent Y</dt><dd>' . $oSlide->getExtentY() . '</dd>'); $this->append('</dl>'); $this->append('</div>'); foreach ($oSlide->getShapeCollection() as $oShape) { if ($oShape instanceof Group) { foreach ($oShape->getShapeCollection() as $oShapeChild) { $this->displayShapeInfo($oShapeChild); } } else { $this->displayShapeInfo($oShape); } } } }