function wmfOrEmfToPdf($imagePath, &$currentXml) { //Step 1. Detect width/height of image. $imageName = basename($imagePath); $imageOffset = strpos($currentXml, $imageName); if ($imageOffset === False) { return False; } //image not in document, don't worry about it. //header('Content-type: text/xml'); die($currentXml); $dom = simplexml_load_string($currentXml); $xpath = "//*[@xlink:href='" . $imageName . "']//parent::draw:frame"; $imageMatch = $dom->xpath($xpath); if (count($imageMatch) == 0) { webServiceError('&error-process-convertimages-no-dom;', 500, array('xpath' => $xpath)); } $imageMatch = $imageMatch[0]; $attributes = $imageMatch->attributes('svg', true); $width = (string) $attributes['width']; $height = (string) $attributes['height']; //Step 2. Make an ODT file containing only the WMF/EMF // (ugh.. I know, but it works and it's reliable because we benefit from OpenOffice's years of // reverse-engineering the EMF/WMF formats so really we should get over it) //step 2a -- make a working directory for our OpenDocument file and copy the files in $workingDirectory = getTemporaryDirectoryInsideDirectory($this->contentDirectory); mkdir($workingDirectory . DIRECTORY_SEPARATOR . 'Pictures'); $destinationImagePath = $workingDirectory . DIRECTORY_SEPARATOR . 'Pictures' . DIRECTORY_SEPARATOR . basename($imagePath); copy($imagePath, $destinationImagePath); $odtTemplateDirectory = DOCVERT_DIR . 'core' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR; $stylesXml = file_get_contents($odtTemplateDirectory . 'styles.xml'); $stylesXml = str_replace('{{page-width}}', $width, $stylesXml); $stylesXml = str_replace('{{page-height}}', $height, $stylesXml); file_put_contents($workingDirectory . DIRECTORY_SEPARATOR . 'styles.xml', $stylesXml); copy($odtTemplateDirectory . 'settings.xml', $workingDirectory . DIRECTORY_SEPARATOR . 'settings.xml'); copy($odtTemplateDirectory . 'meta.xml', $workingDirectory . DIRECTORY_SEPARATOR . 'meta.xml'); copy($odtTemplateDirectory . 'manifest.rdf', $workingDirectory . DIRECTORY_SEPARATOR . 'manifest.rdf'); copy($odtTemplateDirectory . 'mimetype', $workingDirectory . DIRECTORY_SEPARATOR . 'mimetype'); $contentXml = file_get_contents($odtTemplateDirectory . 'content.xml'); $imageTemplate = '<text:p><draw:frame text:anchor-type="as-char" svg:width="{{width}}" svg:height="{{height}}" draw:z-index="1"><draw:image xlink:href="{{path}}" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/></draw:frame></text:p>'; $imageString = str_replace('{{width}}', $width, $imageTemplate); $imageString = str_replace('{{height}}', $height, $imageString); $imageString = str_replace('{{path}}', 'Pictures/' . basename($destinationImagePath), $imageString); $contentXml = str_replace('<!--{{content}}-->', $imageString, $contentXml); file_put_contents($workingDirectory . DIRECTORY_SEPARATOR . 'content.xml', $contentXml); mkdir($workingDirectory . DIRECTORY_SEPARATOR . 'META-INF'); $manifestXml = file_get_contents($odtTemplateDirectory . 'manifest.xml'); $manifestItemTemplate = ' <manifest:file-entry manifest:media-type="" manifest:full-path="{{path}}"/>'; $manifestItem = str_replace('{{path}}', 'Pictures/' . basename($imagePath), $manifestItemTemplate); $manifestXml = str_replace('<!--{{content}}-->', $manifestItem, $manifestXml); file_put_contents($workingDirectory . DIRECTORY_SEPARATOR . 'META-INF' . DIRECTORY_SEPARATOR . 'manifest.xml', $manifestXml); //step 2b zip it into an ODT $zipPath = $this->contentDirectory . DIRECTORY_SEPARATOR . basename($imagePath) . '.odt'; $zipPath = zipFiles($workingDirectory, $zipPath); $zipData = file_get_contents($zipPath); silentlyUnlink($zipPath); silentlyUnlink($workingDirectory); //Step 3 . Stream it to PyODConverter. Make a PDF and save it. $pyodConverterPath = DOCVERT_DIR . 'core' . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'pyodconverter' . DIRECTORY_SEPARATOR . 'pyodconverter.py'; if (!file_exists($pyodConverterPath)) { die("Can't find PyODconverter at " . htmlentities($pyodConverterPath)); } $command = $pyodConverterPath . ' --stream --pdf'; $response = shellCommand($command, 20, $zipData, false); $pdfMagicBytes = '%PDF'; if (substr($response['stdOut'], 0, strlen($pdfMagicBytes)) != $pdfMagicBytes) { die("Expected a PDF response was didn't receive one. Received back " . htmlentities(print_r($response, true))); } $imagePathInfo = pathinfo($imagePath); $pdfPath = dirname($imagePath) . DIRECTORY_SEPARATOR . basename($imagePath, '.' . $imagePathInfo['extension']) . '.pdf'; file_put_contents($pdfPath, $response['stdOut']); return array('width' => $width, 'height' => $height, 'path' => $pdfPath); }
foreach ($zipsInPreviewDirectory as $zipInPreviewDirectory) { silentlyUnlink($zipInPreviewDirectory); if (file_exists($zipInPreviewDirectory)) { webServiceError('Docvert internal error: unable to remove ZIP file at "' . $zipInPreviewDirectory . '"'); } } $zipFilePath = $zipsInPreviewDirectory[0]; } else { $zipFileName = chooseNameOfZipFile($allDocumentsPreviewDirectory); $zipFilePath = $allDocumentsPreviewDirectory . $zipFileName; } $filesInPreviewDirectory = glob($previewDirectory . '*'); foreach ($filesInPreviewDirectory as $fileInPreviewDirectory) { if (!stringStartsWith(basename($fileInPreviewDirectory), "docvert") && !stringEndsWith(basename($fileInPreviewDirectory), "wmf") && !stringEndsWith(basename($fileInPreviewDirectory), "gif") && !stringEndsWith(basename($fileInPreviewDirectory), "png") && !stringEndsWith(basename($fileInPreviewDirectory), "jpeg") && !stringEndsWith(basename($fileInPreviewDirectory), "jpg") && !stringEndsWith(basename($fileInPreviewDirectory), "svg")) { //print 'Delete: '.$fileInPreviewDirectory.'<br />'; silentlyUnlink($fileInPreviewDirectory); } else { //print 'Retain: '.$fileInPreviewDirectory.'<br />'; } } $docbookPath = $previewDirectory . 'docvert--all-docbook.xml'; $docbook = file_get_contents($docbookPath); $docbook = str_replace('{{body}}', $docbookBody, $docbook); $docbook = str_replace('{{title}}', $docbookTitle, $docbook); $contentPath = $previewDirectory . 'content.xml'; file_put_contents($contentPath, $docbook); $pipelineToUse = $pipeline; $autoPipeline = $autopipeline; $skipAheadToDocbook = true; $pipelinePreviewDirectory = 'writable' . DIRECTORY_SEPARATOR . $documentPathParts[0]; applyPipeline($contentPath, $pipelineToUse, $autoPipeline, $pipelinePreviewDirectory, $skipAheadToDocbook);
/** * Recursively deletes a file but doesn't complain if it wasn't able to * Eg. due to permissions */ function silentlyUnlink($path) { if (is_dir($path)) { $pathContainsItems = glob($path . DIRECTORY_SEPARATOR . '*'); foreach ($pathContainsItems as $pathContainsItem) { silentlyUnlink($pathContainsItem); } if (@(!rmdir($path))) { silentlyAppendLineToLog('Unable to delete directory ' . $path, 'error'); } } else { if (@(!unlink($path))) { silentlyAppendLineToLog('Unable to delete file ' . $path, 'error'); } } }