/** * Save PHPPowerPoint 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\\PhpPowerpoint\\Writer\\PowerPoint2007\\Drawing'); } $wPartContentTypes = $this->getWriterPart('ContentTypes'); if (!$wPartContentTypes instanceof ContentTypes) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\PowerPoint2007\\ContentTypes'); } $wPartRels = $this->getWriterPart('Rels'); if (!$wPartRels instanceof Rels) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\PowerPoint2007\\Rels'); } $wPartDocProps = $this->getWriterPart('DocProps'); if (!$wPartDocProps instanceof DocProps) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\PowerPoint2007\\DocProps'); } $wPartTheme = $this->getWriterPart('Theme'); if (!$wPartTheme instanceof Theme) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\PowerPoint2007\\Theme'); } $wPartPresentation = $this->getWriterPart('Presentation'); if (!$wPartPresentation instanceof Presentation) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\PowerPoint2007\\Presentation'); } $wPartSlide = $this->getWriterPart('Slide'); if (!$wPartSlide instanceof Slide) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\PowerPoint2007\\Slide'); } $wPartChart = $this->getWriterPart('Chart'); if (!$wPartChart instanceof Chart) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\PowerPoint2007\\Chart'); } $wPptProps = $this->getWriterPart('PptProps'); if (!$wPptProps instanceof PptProps) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\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()); $objZip->addFromString('ppt/tableStyles.xml', $wPptProps->writeTableStyles()); $objZip->addFromString('ppt/viewProps.xml', $wPptProps->writeViewProps()); // 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)); $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', utf8_encode($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) { // Add slide $objZip->addFromString('ppt/slides/_rels/slide' . ($i + 1) . '.xml.rels', $wPartRels->writeSlideRelationships($this->presentation->getSlide($i))); $objZip->addFromString('ppt/slides/slide' . ($i + 1) . '.xml', $wPartSlide->writeSlide($this->presentation->getSlide($i))); } // 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}."); } @unlink($pFilename); } } else { throw new \Exception("PHPPowerPoint object unassigned."); } }
/** * @expectedException \Exception * @expectedExceptionMessage Invalid array parameter passed. */ public function testAddException() { $object = new HashTable(); $oSlide = new Slide(); $object->addFromSource($oSlide); }
/** * Save PHPPowerPoint 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; } } $writerPartChart = $this->getWriterPart('charts'); if (!$writerPartChart instanceof ObjectsChart) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\ODPresentation\\ObjectsChart'); } $writerPartContent = $this->getWriterPart('content'); if (!$writerPartContent instanceof Content) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\ODPresentation\\Content'); } $writerPartDrawing = $this->getWriterPart('Drawing'); if (!$writerPartDrawing instanceof Drawing) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\ODPresentation\\Drawing'); } $writerPartManifest = $this->getWriterPart('manifest'); if (!$writerPartManifest instanceof Manifest) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\ODPresentation\\Manifest'); } $writerPartMeta = $this->getWriterPart('meta'); if (!$writerPartMeta instanceof Meta) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\ODPresentation\\Meta'); } $writerPartMimetype = $this->getWriterPart('mimetype'); if (!$writerPartMimetype instanceof Mimetype) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\ODPresentation\\Mimetype'); } $writerPartStyles = $this->getWriterPart('styles'); if (!$writerPartStyles instanceof Styles) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Writer\\ODPresentation\\Styles'); } // Create drawing dictionary $this->drawingHashTable->addFromSource($writerPartDrawing->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 mimetype to ZIP file //@todo Not in ZIPARCHIVE::CM_STORE mode $objZip->addFromString('mimetype', $writerPartMimetype->writePart()); // Add content.xml to ZIP file $objZip->addFromString('content.xml', $writerPartContent->writePart($this->presentation)); // Add meta.xml to ZIP file $objZip->addFromString('meta.xml', $writerPartMeta->writePart($this->presentation)); // Add styles.xml to ZIP file $objZip->addFromString('styles.xml', $writerPartStyles->writePart($this->presentation)); // Add META-INF/manifest.xml $objZip->addFromString('META-INF/manifest.xml', $writerPartManifest->writePart()); // Add charts foreach ($this->chartArray as $keyChart => $shapeChart) { $arrayFile = $writerPartChart->writePart($shapeChart); foreach ($arrayFile as $file => $content) { if (!empty($content)) { $objZip->addFromString('Object ' . $keyChart . '/' . $file, $content); } } } // Add media $arrMedia = array(); for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) { $shape = $this->getDrawingHashTable()->getByIndex($i); if (!$shape instanceof AbstractDrawing) { throw new \Exception('The $parentWriter is not an instance of \\PhpOffice\\PhpPowerpoint\\Shape\\AbstractDrawing'); } if ($shape instanceof ShapeDrawing) { if (!in_array(md5($shape->getPath()), $arrMedia)) { $arrMedia[] = md5($shape->getPath()); $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('Pictures/' . md5($shape->getPath()) . '.' . $shape->getExtension(), $imageContents); } } elseif ($shape instanceof MemoryDrawing) { if (!in_array(str_replace(' ', '_', $shape->getIndexedFilename()), $arrMedia)) { $arrMedia[] = str_replace(' ', '_', $shape->getIndexedFilename()); ob_start(); call_user_func($shape->getRenderingFunction(), $shape->getImageResource()); $imageContents = ob_get_contents(); ob_end_clean(); $objZip->addFromString('Pictures/' . str_replace(' ', '_', $shape->getIndexedFilename()), $imageContents); } } } // 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 deleted.'); } } } else { throw new \Exception("PHPPowerPoint object unassigned."); } }