Merge pull request #811 from lrq3000/develop
update: Sync odtphp lib (fix a lot of bugs and add a few functionalities)
This commit is contained in:
commit
3247ce2d1b
@ -9,8 +9,9 @@ class SegmentException extends Exception
|
|||||||
* Encoding : ISO-8859-1
|
* Encoding : ISO-8859-1
|
||||||
*
|
*
|
||||||
* @copyright GPL License 2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com)
|
* @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
|
* @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
|
class Segment implements IteratorAggregate, Countable
|
||||||
{
|
{
|
||||||
@ -93,7 +94,10 @@ class Segment implements IteratorAggregate, Countable
|
|||||||
$this->file->open($this->odf->getTmpfile());
|
$this->file->open($this->odf->getTmpfile());
|
||||||
foreach ($this->images as $imageKey => $imageValue) {
|
foreach ($this->images as $imageKey => $imageValue) {
|
||||||
if ($this->file->getFromName('Pictures/' . $imageValue) === false) {
|
if ($this->file->getFromName('Pictures/' . $imageValue) === false) {
|
||||||
|
// Add the image inside the ODT document
|
||||||
$this->file->addFile($imageKey, 'Pictures/' . $imageValue);
|
$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();
|
$this->file->close();
|
||||||
@ -153,11 +157,16 @@ class Segment implements IteratorAggregate, Countable
|
|||||||
if ($size === false) {
|
if ($size === false) {
|
||||||
throw new OdfException("Invalid image");
|
throw new OdfException("Invalid image");
|
||||||
}
|
}
|
||||||
|
// Set the width and height of the page
|
||||||
list ($width, $height) = $size;
|
list ($width, $height) = $size;
|
||||||
$width *= Odf::PIXEL_TO_CM;
|
$width *= Odf::PIXEL_TO_CM;
|
||||||
$height *= 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
|
$xml = <<<IMG
|
||||||
<draw:frame draw:style-name="fr1" draw:name="$filename" text:anchor-type="char" svg:width="{$width}cm" svg:height="{$height}cm" draw:z-index="3"><draw:image xlink:href="Pictures/$file" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/></draw:frame>
|
<draw:frame draw:style-name="fr1" draw:name="$filename" text:anchor-type="aschar" svg:width="{$width}cm" svg:height="{$height}cm" draw:z-index="3"><draw:image xlink:href="Pictures/$file" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/></draw:frame>
|
||||||
IMG;
|
IMG;
|
||||||
$this->images[$value] = $file;
|
$this->images[$value] = $file;
|
||||||
$this->setVars($key, $xml, false);
|
$this->setVars($key, $xml, false);
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
require_once 'zip/PclZipProxy.php';
|
||||||
|
require_once 'zip/PhpZipProxy.php';
|
||||||
require 'Segment.php';
|
require 'Segment.php';
|
||||||
class OdfException extends Exception
|
class OdfException extends Exception
|
||||||
{}
|
{}
|
||||||
@ -10,8 +12,10 @@ class OdfException extends Exception
|
|||||||
*
|
*
|
||||||
* @copyright GPL License 2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com)
|
* @copyright GPL License 2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com)
|
||||||
* @copyright GPL License 2010 - Laurent Destailleur - eldy@users.sourceforge.net
|
* @copyright GPL License 2010 - Laurent Destailleur - eldy@users.sourceforge.net
|
||||||
|
* @copyright GPL License 2010 - Vikas Mahajan - http://vikasmahajan.wordpress.com
|
||||||
|
* @copyright GPL License 2012 - Stephen Larroque - lrq3000@gmail.com
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GPL License
|
* @license http://www.gnu.org/copyleft/gpl.html GPL License
|
||||||
* @version 1.4.3 (last update 2012-07-29)
|
* @version 1.4.6 (last update 2013-04-07)
|
||||||
*/
|
*/
|
||||||
class Odf
|
class Odf
|
||||||
{
|
{
|
||||||
@ -82,7 +86,7 @@ class Odf
|
|||||||
throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'");
|
throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'");
|
||||||
}
|
}
|
||||||
if (($this->manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) {
|
if (($this->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) {
|
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'");
|
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')
|
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:
|
// TODO Warning string may be:
|
||||||
// <text:span text:style-name="T13">{</text:span><text:span text:style-name="T12">aaa</text:span><text:span text:style-name="T13">}</text:span>
|
// <text:span text:style-name="T13">{</text:span><text:span text:style-name="T12">aaa</text:span><text:span text:style-name="T13">}</text:span>
|
||||||
// instead of {aaa} so we should enhance this function.
|
// instead of {aaa} so we should enhance this function.
|
||||||
//print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'<br>';
|
//print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'<br>';
|
||||||
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 . '</text;span>') === false) {
|
//if (strpos($this->contentXml, '">'. $key . '</text;span>') === false) {
|
||||||
throw new OdfException("var $key not found in the document");
|
throw new OdfException("var $key not found in the document");
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
$value = $encode ? htmlspecialchars($value) : $value;
|
$value = $encode ? htmlspecialchars($value) : $value;
|
||||||
$value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value;
|
$value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value;
|
||||||
$this->vars[$this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']] = str_replace("\n", "<text:line-break/>", $value);
|
$this->vars[$tag] = str_replace("\n", "<text:line-break/>", $value);
|
||||||
return $this;
|
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<content>.+)\?[\}\>]/iU',$this->contentXml, $matches); // detecting all {?php code ?} or <?php code ? >
|
||||||
|
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
|
* Assign a template variable as a picture
|
||||||
*
|
*
|
||||||
@ -145,7 +174,7 @@ class Odf
|
|||||||
$width *= self::PIXEL_TO_CM;
|
$width *= self::PIXEL_TO_CM;
|
||||||
$height *= self::PIXEL_TO_CM;
|
$height *= self::PIXEL_TO_CM;
|
||||||
$xml = <<<IMG
|
$xml = <<<IMG
|
||||||
<draw:frame draw:style-name="fr1" draw:name="$filename" text:anchor-type="char" svg:width="{$width}cm" svg:height="{$height}cm" draw:z-index="3"><draw:image xlink:href="Pictures/$file" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/></draw:frame>
|
<draw:frame draw:style-name="fr1" draw:name="$filename" text:anchor-type="aschar" svg:width="{$width}cm" svg:height="{$height}cm" draw:z-index="3"><draw:image xlink:href="Pictures/$file" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/></draw:frame>
|
||||||
IMG;
|
IMG;
|
||||||
$this->images[$value] = $file;
|
$this->images[$value] = $file;
|
||||||
$this->setVars($key, $xml, false);
|
$this->setVars($key, $xml, false);
|
||||||
@ -333,8 +362,10 @@ IMG;
|
|||||||
throw new OdfException('Error during file export addFromString');
|
throw new OdfException('Error during file export addFromString');
|
||||||
}
|
}
|
||||||
foreach ($this->images as $imageKey => $imageValue) {
|
foreach ($this->images as $imageKey => $imageValue) {
|
||||||
|
// Add the image inside the ODT document
|
||||||
$this->file->addFile($imageKey, 'Pictures/' . $imageValue);
|
$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)) {
|
if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) {
|
||||||
throw new OdfException('Error during file export: manifest.xml');
|
throw new OdfException('Error during file export: manifest.xml');
|
||||||
@ -349,15 +380,18 @@ IMG;
|
|||||||
*/
|
*/
|
||||||
public function addImageToManifest($file)
|
public function addImageToManifest($file)
|
||||||
{
|
{
|
||||||
$extension = explode('.', $file);
|
// Get the file extension
|
||||||
$add = ' <manifest:file-entry manifest:media-type="image/'.$extension[1].'" manifest:full-path="Pictures/'.$file.'"/>'."\n";
|
$ext = substr(strrchr($val, '.'), 1);
|
||||||
$this->manifestXml = str_replace('</manifest:manifest>', $add.'</manifest:manifest>', $this->manifestXml);
|
// 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 = ' <manifest:file-entry manifest:media-type="image/'.$ext.'" manifest:full-path="Pictures/'.$file.'"/>'."\n";
|
||||||
|
// Append the image to the manifest
|
||||||
|
$this->manifestXml = str_replace('</manifest:manifest>', $add.'</manifest:manifest>', $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
|
* Export the file as attached file by HTTP
|
||||||
*
|
*
|
||||||
* @param string $name (optionnal)
|
* @param string $name (optional)
|
||||||
* @throws OdfException
|
* @throws OdfException
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
@ -375,8 +409,42 @@ IMG;
|
|||||||
|
|
||||||
header('Content-type: application/vnd.oasis.opendocument.text');
|
header('Content-type: application/vnd.oasis.opendocument.text');
|
||||||
header('Content-Disposition: attachment; filename="'.$name.'"');
|
header('Content-Disposition: attachment; filename="'.$name.'"');
|
||||||
|
header('Content-Length: '.filesize($this->tmpfile));
|
||||||
readfile($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:<br>";
|
||||||
|
foreach($output as $line)
|
||||||
|
echo $line."<br>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a variable of configuration
|
* Returns a variable of configuration
|
||||||
*
|
*
|
||||||
|
|||||||
22
htdocs/includes/odtphp/odt2pdf.sh
Normal file
22
htdocs/includes/odtphp/odt2pdf.sh
Normal file
@ -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
|
||||||
Loading…
Reference in New Issue
Block a user