From 6e1e41e8b562e20f72a93a1d42542971b2db2275 Mon Sep 17 00:00:00 2001 From: Stephen L Date: Sun, 7 Apr 2013 17:27:35 +0200 Subject: [PATCH] update: Sync odtphp lib (fix a lot of bugs and add a few functionalities) Ref: https://github.com/lrq3000/odtphp/commit/b4e02a1306f4d5888b076dea808effe449b9cf3d Signed-off-by: Stephen L. --- htdocs/includes/odtphp/Segment.php | 13 ++++- htdocs/includes/odtphp/odf.php | 88 ++++++++++++++++++++++++++---- htdocs/includes/odtphp/odt2pdf.sh | 22 ++++++++ 3 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 htdocs/includes/odtphp/odt2pdf.sh diff --git a/htdocs/includes/odtphp/Segment.php b/htdocs/includes/odtphp/Segment.php index 0a3ad21c7f2..7a6e15ee48b 100644 --- a/htdocs/includes/odtphp/Segment.php +++ b/htdocs/includes/odtphp/Segment.php @@ -9,8 +9,9 @@ class SegmentException extends Exception * Encoding : ISO-8859-1 * * @copyright GPL License 2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com) + * @copyright GPL License 2012 - Stephen Larroque - lrq3000@gmail.com * @license http://www.gnu.org/copyleft/gpl.html GPL License - * @version 1.3 + * @version 1.4.5 (last update 2013-04-07) */ class Segment implements IteratorAggregate, Countable { @@ -93,7 +94,10 @@ class Segment implements IteratorAggregate, Countable $this->file->open($this->odf->getTmpfile()); foreach ($this->images as $imageKey => $imageValue) { if ($this->file->getFromName('Pictures/' . $imageValue) === false) { + // Add the image inside the ODT document $this->file->addFile($imageKey, 'Pictures/' . $imageValue); + // Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice) + $this->odf->addImageToManifest($imageValue); } } $this->file->close(); @@ -153,11 +157,16 @@ class Segment implements IteratorAggregate, Countable if ($size === false) { throw new OdfException("Invalid image"); } + // Set the width and height of the page list ($width, $height) = $size; $width *= Odf::PIXEL_TO_CM; $height *= Odf::PIXEL_TO_CM; + // Fix local-aware issues (eg: 12,10 -> 12.10) + $width = sprintf("%F", $width); + $height = sprintf("%F", $height); + $xml = << + IMG; $this->images[$value] = $file; $this->setVars($key, $xml, false); diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 1d2fea6001f..2d5c991fb77 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -1,4 +1,6 @@ manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) { - throw new OdfException("Something is wrong with META-INF/manifest.xm in source file '$filename'"); + throw new OdfException("Something is wrong with META-INF/manifest.xml in source file '$filename'"); } if (($this->stylesXml = $this->file->getFromName('styles.xml')) === false) { throw new OdfException("Nothing to parse - Check that the styles.xml file is correctly formed in source file '$filename'"); @@ -110,21 +114,46 @@ class Odf */ public function setVars($key, $value, $encode = true, $charset = 'ISO-8859') { + $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; // TODO Warning string may be: // {aaa} // instead of {aaa} so we should enhance this function. //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; - if (strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']) === false) { + if (strpos($this->contentXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { //if (strpos($this->contentXml, '">'. $key . '') === false) { throw new OdfException("var $key not found in the document"); //} } $value = $encode ? htmlspecialchars($value) : $value; $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; - $this->vars[$this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']] = str_replace("\n", "", $value); + $this->vars[$tag] = str_replace("\n", "", $value); return $this; } + /** + * Evaluating php codes inside the ODT and output the buffer (print, echo) inplace of the code + * + */ + public function phpEval() + { + preg_match_all('/[\{\<]\?(php)?\s+(?P.+)\?[\}\>]/iU',$this->contentXml, $matches); // detecting all {?php code ?} or + for ($i=0;$i < count($matches['content']);$i++) { + try { + $ob_output = ''; // flush the output for each code. This var will be filled in by the eval($code) and output buffering : any print or echo or output will be redirected into this variable + $code = $matches['content'][$i]; + ob_start(); + eval ($code); + $ob_output = ob_get_contents(); // send the content of the buffer into $ob_output + $this->contentXml = str_replace($matches[0][$i], $ob_output, $this->contentXml); + ob_end_clean(); + } catch (Exception $e) { + ob_end_clean(); + $this->contentXml = str_replace($matches[0][$i], 'ERROR: there was a problem while evaluating this portion of code, please fix it: '.$e, $this->contentXml); + } + } + return 0; + } + /** * Assign a template variable as a picture * @@ -145,7 +174,7 @@ class Odf $width *= self::PIXEL_TO_CM; $height *= self::PIXEL_TO_CM; $xml = << + IMG; $this->images[$value] = $file; $this->setVars($key, $xml, false); @@ -333,8 +362,10 @@ IMG; throw new OdfException('Error during file export addFromString'); } foreach ($this->images as $imageKey => $imageValue) { + // Add the image inside the ODT document $this->file->addFile($imageKey, 'Pictures/' . $imageValue); - $this->addImageToManifest($imageValue); + // Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice) + $this->addImageToManifest($imageValue); } if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) { throw new OdfException('Error during file export: manifest.xml'); @@ -349,15 +380,18 @@ IMG; */ public function addImageToManifest($file) { - $extension = explode('.', $file); - $add = ' '."\n"; - $this->manifestXml = str_replace('', $add.'', $this->manifestXml); + // Get the file extension + $ext = substr(strrchr($val, '.'), 1); + // Create the correct image XML entry to add to the manifest (this is necessary because ODT format requires that we keep a list of the images in the manifest.xml) + $add = ' '."\n"; + // Append the image to the manifest + $this->manifestXml = str_replace('', $add.'', $this->manifestXml); // we replace the manifest closing tag by the image XML entry + manifest closing tag (this results in appending the data, we do not overwrite anything) } /** * Export the file as attached file by HTTP * - * @param string $name (optionnal) + * @param string $name (optional) * @throws OdfException * @return void */ @@ -375,8 +409,42 @@ IMG; header('Content-type: application/vnd.oasis.opendocument.text'); header('Content-Disposition: attachment; filename="'.$name.'"'); + header('Content-Length: '.filesize($this->tmpfile)); readfile($this->tmpfile); } + + /** + * Convert the ODT file to PDF and export the file as attached file by HTTP + * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh + * + * @param string $name (optional) + * @throws OdfException + * @return void + */ + public function exportAsAttachedPDF($name="") + { + if( $name == "" ) $name = md5(uniqid()); + + $this->saveToDisk("$name.odt"); + exec("./odt2pdf.sh $name",$output,$ret_val); + if($ret_val == 0) + { + if (headers_sent($filename, $linenum)) { + throw new OdfException("headers already sent ($filename at $linenum)"); + } + + header('Content-type: application/pdf'); + header('Content-Disposition: attachment; filename="'.$name.'.pdf"'); + readfile("$name.pdf"); + unlink("$name.odt"); + unlink("$name.pdf"); + } else { + echo "Error occured:
"; + foreach($output as $line) + echo $line."
"; + } + } + /** * Returns a variable of configuration * diff --git a/htdocs/includes/odtphp/odt2pdf.sh b/htdocs/includes/odtphp/odt2pdf.sh new file mode 100644 index 00000000000..b9710682465 --- /dev/null +++ b/htdocs/includes/odtphp/odt2pdf.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# @copyright GPL License 2010 - Vikas Mahajan - http://vikasmahajan.wordpress.com + +if [ -f "$1.odt" ] +then +pgrep -U `id -u` soffice +if [ $? -ne 0 ] +then +soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard +sleep 2 +fi +jodconverter "$1.odt" "$1.pdf" +if [ $? -ne 0 ] +then +echo "Error while converting odt to pdf" +exit 1 +fi +sleep 1 +else +echo "Error: Odt file does not exist" +exit 1 +fi