mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 12:19:28 +00:00
720 lines
20 KiB
PHP
720 lines
20 KiB
PHP
<?php
|
|
/* Copyright (C) 2024 fhcomplete.net
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
*/
|
|
|
|
if (!defined('BASEPATH')) exit('No direct script access allowed');
|
|
|
|
use stdClass as stdClass;
|
|
use DOMDocument as DOMDocument;
|
|
use XSLTProcessor as XSLTProcessor;
|
|
use SimpleXMLElement as SimpleXMLElement;
|
|
|
|
/**
|
|
* This library replaces the old document_export.class except for the convert
|
|
* function which is located in the DocumentLib library.
|
|
*
|
|
* The usage differs a little bit from the old library:
|
|
* In the old library you had to call create() then some optional function
|
|
* for adding data (addDataArray()/addDataXML()/addDataURL()/setFilename()),
|
|
* modifiing said data (sign()/setXMLTag_archivierbar()) or adding
|
|
* images (addImage()) and then call output() and close().
|
|
* Now the create, output and close functions are combined into one function and adding data and images is done via parameters.
|
|
* There are now two functions getContent() and showContent() where showContent() equals to output(false) and getContent equals to output(true)
|
|
* Instead of calling addDataArray, addDataXML or addDataURL just call
|
|
* getDataArray, getDataXML or getDataURL respectevily and use the return
|
|
* value as $xml_data parameter in the showContent and getContent calls.
|
|
* Instead of calling addImages just create an array and pass it as $images
|
|
* parameter to the showContent/getContent function.
|
|
* The old setFilename() function is now a parameter in showContent(). It is
|
|
* not needed in getContent() since that function does not do anything that
|
|
* requires a filename.
|
|
* To get/show a signed document just pass a valid uid as $sign_user
|
|
* parameter.
|
|
*
|
|
* Example:
|
|
* Old:
|
|
* $doc = new document_export($vorlage->vorlage_kurzbz, $oe_kurzbz, $version);
|
|
* $doc->setFilename($filename);
|
|
* $doc->addDataXML($data);
|
|
* $doc->addImage($imagepath, $imagename, $imagecontenttype);
|
|
* $doc->create($outputformat);
|
|
* $doc->output(true);
|
|
* $doc->close();
|
|
*
|
|
* New:
|
|
* $xml_data = $this->documentexportlib->getDataXML($data);
|
|
* $images = [[
|
|
* 'path' => $imagepath,
|
|
* 'name' => $imagename,
|
|
* 'contenttype' => $imagecontenttype
|
|
* ]];
|
|
* $this->documentexportlib->showContent(
|
|
* $filename,
|
|
* $vorlage,
|
|
* $xml_data,
|
|
* $oe_kurzbz,
|
|
* $version,
|
|
* $outputformat,
|
|
* null,
|
|
* null,
|
|
* $images
|
|
* );
|
|
*/
|
|
class DocumentExportLib
|
|
{
|
|
private $unoconv_version;
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public function __construct()
|
|
{
|
|
// Gets CI instance
|
|
$this->ci =& get_instance();
|
|
|
|
// Load Phrases
|
|
$this->ci->load->library('PhrasesLib', ['document_export', null], 'documentExportPhrases');
|
|
|
|
// Which document converter has to be used
|
|
if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true)
|
|
{
|
|
// Use docsbox!!
|
|
}
|
|
else
|
|
{
|
|
exec('unoconv --version', $ret_arr);
|
|
|
|
if(isset($ret_arr[0]))
|
|
{
|
|
$hlp = explode(' ', $ret_arr[0]);
|
|
if(isset($hlp[1]))
|
|
{
|
|
$this->unoconv_version = $hlp[1];
|
|
}
|
|
else
|
|
show_error($this->ci->documentExportPhrases->t("document_export", "error_unoconv_version"));
|
|
}
|
|
else
|
|
show_error($this->ci->documentExportPhrases->t("document_export", "error_unoconv"));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Laedt die XML Daten fuer die XSL Transformation anhand eines Arrays
|
|
*
|
|
* @param array $data Array mit Daten
|
|
* @param string $root Bezeichnung des Root Nodes
|
|
*
|
|
* @return DOMDocument
|
|
*/
|
|
public function getDataArray($data, $root)
|
|
{
|
|
$xml_data = new DOMDocument();
|
|
$xml_data->loadXML($this->convertArrayToXML($data, $root));
|
|
return $xml_data;
|
|
}
|
|
|
|
/**
|
|
* XML Daten fuer die XSL Transformation
|
|
*
|
|
* @param string $xml
|
|
*
|
|
* @return DOMDocument
|
|
*/
|
|
public function getDataXML($xml)
|
|
{
|
|
$xml_data = new DOMDocument();
|
|
$xml_data->loadXML($xml);
|
|
return $xml_data;
|
|
}
|
|
|
|
/**
|
|
* URL zu XML Datei die fuer XSLTransformation verwendet werden soll
|
|
*
|
|
* @param string $xml URL to XML
|
|
* @param string $params GET parameter
|
|
*
|
|
* @return stdClass
|
|
*/
|
|
public function getDataURL($xml, $params)
|
|
{
|
|
$xml_found = false;
|
|
|
|
$aktive_addons = array_filter(array_map('trim', explode(";", ACTIVE_ADDONS)));
|
|
foreach($aktive_addons as $addon) {
|
|
$xmlfile = DOC_ROOT . 'addons/' . $addon . '/rdf/' . $xml;
|
|
if (file_exists($xmlfile)) {
|
|
$xml_found = true;
|
|
$xml_url = XML_ROOT . '../addons/' . $addon . '/rdf/' . $xml . '?' . $params;
|
|
break;
|
|
}
|
|
}
|
|
if (!$xml_found)
|
|
$xml_url = XML_ROOT . $xml . '?' . $params;
|
|
|
|
|
|
// Load the XML source
|
|
$xml_data = new DOMDocument;
|
|
|
|
if (!$xml_data->load($xml_url))
|
|
return error($this->ci->documentExportPhrases->t("document_export", "error_xml_load", [
|
|
"url" => $xml_url,
|
|
"xml" => $xml,
|
|
"params" => $params
|
|
]));
|
|
|
|
return success($xml_data);
|
|
}
|
|
|
|
/**
|
|
* Adds a XML Tag for signatur to the document
|
|
*
|
|
* @param DomDocument $xml_data
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function addSignToData($xml_data)
|
|
{
|
|
$signblock = $xml_data->createElement("signed", "true");
|
|
$xml_data->documentElement->appendChild($signblock);
|
|
}
|
|
|
|
/**
|
|
* Adds a XML Tag for archive to the document
|
|
*
|
|
* @param DomDocument $xml_data
|
|
*
|
|
* @return void
|
|
*/
|
|
public function addArchiveToData($xml_data)
|
|
{
|
|
$archiv = $xml_data->createElement("archivierbar", "true");
|
|
$xml_data->documentElement->appendChild($archiv);
|
|
}
|
|
|
|
/**
|
|
* Get the contents of a Document
|
|
*
|
|
* @param stdClass $vorlage A db entry from tbl_vorlage
|
|
* @param DomDocument $xml_data
|
|
* @param string $oe_kurzbz
|
|
* @param integer|null $version (optional)
|
|
* @param string $outputformat (optional)
|
|
* @param string $sign_user (optional) Must be a valid uid
|
|
* @param string $sign_profile (optional) Signatureprofile for signing
|
|
* @param array $images (optional) Each element should have a property path, name & contenttype which are all strings
|
|
*
|
|
* @return stdClass
|
|
*/
|
|
public function getContent(
|
|
$vorlage,
|
|
$xml_data,
|
|
$oe_kurzbz,
|
|
$version = null,
|
|
$outputformat = null,
|
|
$sign_user = null,
|
|
$sign_profile = null,
|
|
$images = []
|
|
) {
|
|
$source_folder = getcwd();
|
|
$temp_folder = sys_get_temp_dir() . '/fhcunoconv-' . uniqid();
|
|
|
|
$outputformat = $this->getDefaultOutputFormat($outputformat, $vorlage->mimetype);
|
|
|
|
$result = $this->createAndSignContent(
|
|
$temp_folder,
|
|
$outputformat,
|
|
$vorlage,
|
|
$oe_kurzbz,
|
|
$version,
|
|
$xml_data,
|
|
$images,
|
|
$sign_user,
|
|
$sign_profile
|
|
);
|
|
if (isError($result)) {
|
|
$this->close($temp_folder, $source_folder);
|
|
return $result;
|
|
}
|
|
$temp_filename = getData($result);
|
|
|
|
$fsize = filesize($temp_filename);
|
|
$handle = fopen($temp_filename, 'r');
|
|
if (!$handle)
|
|
return error($this->ci->documentExportPhrases->t("document_export", "error_file_load"));
|
|
$result = fread($handle, $fsize);
|
|
fclose($handle);
|
|
|
|
$this->close($temp_folder, $source_folder);
|
|
|
|
return success($result);
|
|
}
|
|
|
|
/**
|
|
* Sets the headers and displays the Document.
|
|
* On failure the exit() function will be called
|
|
*
|
|
* @param string $filename
|
|
* @param stdClass $vorlage A db entry from tbl_vorlage
|
|
* @param DomDocument $xml_data
|
|
* @param string $oe_kurzbz
|
|
* @param integer|null $version (optional)
|
|
* @param string $outputformat (optional)
|
|
* @param string $sign_user (optional) Must be a valid uid
|
|
* @param string $sign_profile (optional) Signatureprofile for signing
|
|
* @param array $images (optional) Each element should have a property path, name & contenttype which are all strings
|
|
*
|
|
* @return void
|
|
*/
|
|
public function showContent(
|
|
$filename,
|
|
$vorlage,
|
|
$xml_data,
|
|
$oe_kurzbz,
|
|
$version = null,
|
|
$outputformat = null,
|
|
$sign_user = null,
|
|
$sign_profile = null,
|
|
$images = []
|
|
) {
|
|
$source_folder = getcwd();
|
|
$temp_folder = sys_get_temp_dir() . '/fhcunoconv-' . uniqid();
|
|
|
|
$outputformat = $this->getDefaultOutputFormat($outputformat, $vorlage->mimetype);
|
|
|
|
$result = $this->createAndSignContent(
|
|
$temp_folder,
|
|
$outputformat,
|
|
$vorlage,
|
|
$oe_kurzbz,
|
|
$version,
|
|
$xml_data,
|
|
$images,
|
|
$sign_user,
|
|
$sign_profile
|
|
);
|
|
if (isError($result)) {
|
|
$this->close($temp_folder, $source_folder);
|
|
exit(getError($result));
|
|
}
|
|
$temp_filename = getData($result);
|
|
|
|
$fsize = filesize($temp_filename);
|
|
$handle = fopen($temp_filename, 'r');
|
|
if (!$handle) {
|
|
$this->close($temp_folder, $source_folder);
|
|
exit($this->ci->documentExportPhrases->t("document_export", "error_file_load"));
|
|
}
|
|
|
|
if (headers_sent()) {
|
|
$this->close($temp_folder, $source_folder);
|
|
exit($this->ci->documentExportPhrases->t("document_export", "error_headers"));
|
|
}
|
|
|
|
switch ($outputformat) {
|
|
case 'pdf':
|
|
header('Content-type: application/pdf');
|
|
header('Content-Disposition: attachment; filename="' . $filename . '.pdf"');
|
|
header('Content-Length: ' . $fsize);
|
|
break;
|
|
|
|
case 'doc':
|
|
header('Content-type: application/vnd.ms-word');
|
|
header('Content-Disposition: attachment; filename="' . $filename . '.doc"');
|
|
header('Content-Length: ' . $fsize);
|
|
break;
|
|
|
|
case 'odt':
|
|
header('Content-type: application/vnd.oasis.opendocument.text');
|
|
header('Content-Disposition: attachment; filename="' . $filename . '.odt"');
|
|
header('Content-Length: ' . $fsize);
|
|
break;
|
|
default:
|
|
$this->close($temp_folder, $source_folder);
|
|
exit($this->ci->documentExportPhrases->t("document_export", "error_outputformat_missing"));
|
|
}
|
|
|
|
while (!feof($handle)) {
|
|
echo fread($handle, 8192);
|
|
}
|
|
fclose($handle);
|
|
|
|
$this->close($temp_folder, $source_folder);
|
|
}
|
|
|
|
/**
|
|
* Helper function for getContent and showContent.
|
|
* Creates the temp folder and calls create and sign functions.
|
|
*
|
|
* @param string $temp_folder
|
|
* @param string $outputformat
|
|
* @param stdClass $vorlage
|
|
* @param string $oe_kurzbz
|
|
* @param integer $version
|
|
* @param DomDocument $xml_data
|
|
* @param array $images Each element should have a property path, name and contenttype which are all strings
|
|
* @param string $sign_user Must be a valid uid
|
|
* @param string $sign_profile Signatureprofile for signing
|
|
*
|
|
* @return stdClass
|
|
*/
|
|
protected function createAndSignContent(
|
|
$temp_folder,
|
|
$outputformat,
|
|
$vorlage,
|
|
$oe_kurzbz,
|
|
$version,
|
|
$xml_data,
|
|
$images,
|
|
$sign_user,
|
|
$sign_profile
|
|
) {
|
|
mkdir($temp_folder);
|
|
chdir($temp_folder);
|
|
|
|
$this->ci->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel');
|
|
|
|
$result = $this->ci->VorlagestudiengangModel->getCurrent($vorlage->vorlage_kurzbz, $oe_kurzbz, $version);
|
|
if (isError($result))
|
|
return $result;
|
|
if (!hasData($result))
|
|
return error($this->ci->documentExportPhrases->t("document_export", "error_template_missing"));
|
|
$vorlage_stg = current(getData($result));
|
|
foreach ($vorlage_stg as $k => $v)
|
|
$vorlage->$k = $v;
|
|
|
|
if ($sign_user)
|
|
{
|
|
$this->addSignToData($xml_data);
|
|
}
|
|
|
|
$result = $this->create($temp_folder, $outputformat, $vorlage, $xml_data, $images);
|
|
if (isError($result))
|
|
return $result;
|
|
|
|
$temp_filename = getData($result);
|
|
|
|
if ($sign_user)
|
|
{
|
|
$result = $this->sign($temp_folder, $temp_filename, $outputformat, $sign_user, $sign_profile);
|
|
if (isError($result))
|
|
return $result;
|
|
|
|
$temp_filename = getData($result);
|
|
}
|
|
|
|
return success($temp_filename);
|
|
}
|
|
|
|
/**
|
|
* Helper function for createAndSignContent.
|
|
* Creates the files in the temp folder.
|
|
*
|
|
* @param string $temp_folder
|
|
* @param string $outputformat
|
|
* @param stdClass $vorlage
|
|
* @param DomDocument $xml_data
|
|
* @param array $images Each element should have a property path, name and contenttype which are all strings
|
|
*
|
|
* @return stdClass
|
|
*/
|
|
protected function create($temp_folder, $outputformat, $vorlage, $xml_data, $images)
|
|
{
|
|
$content_xsl = new DOMDocument();
|
|
if (!$content_xsl->loadXML($vorlage->text))
|
|
return error($this->ci->documentExportPhrases->t("document_export", "error_xsl_load"));
|
|
|
|
$proc = new XSLTProcessor();
|
|
$proc->importStyleSheet($content_xsl);
|
|
|
|
$contentbuffer = $proc->transformToXml($xml_data);
|
|
|
|
file_put_contents($temp_folder . '/content.xml', $contentbuffer);
|
|
|
|
if ($xml_data->firstChild->tagName == 'error')
|
|
return error($xml_data->firstChild->textContent);
|
|
|
|
$styles_xsl = null;
|
|
// styles.xml erstellen
|
|
if ($vorlage->style) {
|
|
$styles_xsl = new DOMDocument();
|
|
if (!$styles_xsl->loadXML($vorlage->style))
|
|
return error($this->ci->documentExportPhrases->t("document_export", "error_styles_load"));
|
|
$style_proc = new XSLTProcessor();
|
|
$style_proc->importStyleSheet($styles_xsl);
|
|
|
|
$stylesbuffer = $style_proc->transformToXml($xml_data);
|
|
|
|
file_put_contents($temp_folder . '/styles.xml', $stylesbuffer);
|
|
}
|
|
|
|
// Template holen
|
|
$vorlage_found = false;
|
|
$vorlage_filename = $vorlage->vorlage_kurzbz . ($vorlage->mimetype == 'application/vnd.oasis.opendocument.spreadsheet' ? '.ods' : '.odt');
|
|
|
|
$aktive_addons = array_filter(array_map('trim', explode(";", ACTIVE_ADDONS)));
|
|
foreach($aktive_addons as $addon) {
|
|
$zipfile = DOC_ROOT . 'addons/' . $addon . '/system/vorlage_zip/' . $vorlage_filename;
|
|
|
|
if (file_exists($zipfile)) {
|
|
$vorlage_found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!$vorlage_found)
|
|
$zipfile = DOC_ROOT . 'system/vorlage_zip/' . $vorlage_filename;
|
|
|
|
$tempname_zip = $temp_folder . '/out.zip';
|
|
|
|
if (!copy($zipfile, $tempname_zip))
|
|
return error($this->ci->documentExportPhrases->t("document_export", "error_file_copy"));
|
|
|
|
exec("zip $tempname_zip content.xml");
|
|
if (!is_null($styles_xsl))
|
|
exec("zip $tempname_zip styles.xml");
|
|
|
|
// bilder hinzufuegen
|
|
if (count($images) > 0)
|
|
{
|
|
// Unterordner fuer die Bilder erstellen
|
|
mkdir('Pictures');
|
|
|
|
// Manifest Datei holen
|
|
exec('unzip ' . $tempname_zip . ' META-INF/manifest.xml');
|
|
|
|
// Bild zur Manifest Datei hinzufuegen
|
|
$manifest = file_get_contents('META-INF/manifest.xml');
|
|
|
|
$manifest_xml = new DOMDocument;
|
|
if (!$manifest_xml->loadXML($manifest))
|
|
return error($this->ci->documentExportPhrases->t("document_export", "error_manifest"));
|
|
|
|
//root-node holen
|
|
$root = $manifest_xml->getElementsByTagName('manifest')->item(0);
|
|
|
|
foreach ($images as $bild) {
|
|
copy($bild['path'], 'Pictures/' . $bild['name']);
|
|
|
|
//Neues Element unterhalb des Root Nodes anlegen
|
|
$node = $manifest_xml->createElement("manifest:file-entry");
|
|
$node->setAttribute("manifest:full-path", 'Pictures/' . $bild['name']);
|
|
$node->setAttribute("manifest:media-type", $bild['contenttype']);
|
|
$root->appendChild($node);
|
|
}
|
|
|
|
$out = $manifest_xml->saveXML();
|
|
|
|
//geaenderte Manifest Datei speichern und wieder ins Zip packen
|
|
file_put_contents('META-INF/manifest.xml', $out);
|
|
exec('zip ' . $tempname_zip . ' META-INF/*');
|
|
|
|
// Bilder zum ZIP-File hinzufuegen
|
|
exec('zip ' . $tempname_zip . ' Pictures/*');
|
|
}
|
|
|
|
clearstatcache();
|
|
|
|
switch ($outputformat) {
|
|
case 'pdf':
|
|
case 'doc':
|
|
$ret = 0;
|
|
$temp_filename = $temp_folder . '/out.' . $outputformat;
|
|
|
|
if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true) {
|
|
// Use docsbox
|
|
|
|
$this->ci->load->library("DocsboxLib");
|
|
|
|
$docboxlib = get_class($this->ci->docboxlib);
|
|
|
|
$ret = $docboxlib::convert($tempname_zip, $temp_filename, $outputformat);
|
|
} else {
|
|
// Use unoconv
|
|
|
|
// Unoconv Version 0.6 hat eine Bug wodurch die Berechtigungen des PDF/Doc nicht korrekt gesetzt
|
|
// werden. Deshalb wird dies hier speziell behandelt.
|
|
// Die 2. Variante hat den Vorteil dass hier eine bessere Fehlerbehandlung moeglich ist
|
|
if ($this->unoconv_version == '0.6')
|
|
$command = 'unoconv -e IsSkipEmptyPages=false -f ' . $outputformat . ' %2$s > %1$s';
|
|
else
|
|
$command = 'unoconv -e IsSkipEmptyPages=false -f ' . $outputformat . ' --output %s %s 2>&1';
|
|
|
|
$command = sprintf($command, $temp_filename, $tempname_zip);
|
|
|
|
exec($command, $out, $ret);
|
|
}
|
|
|
|
if ($ret)
|
|
return error($this->ci->documentExportPhrases->t("document_export", "error_conv_timeout"));
|
|
break;
|
|
case 'odt':
|
|
default:
|
|
$temp_filename = $tempname_zip;
|
|
}
|
|
|
|
return success($temp_filename);
|
|
}
|
|
|
|
/**
|
|
* Helper function for createAndSignContent.
|
|
* Signs the main file in the temp folder.
|
|
*
|
|
* @param string $temp_folder
|
|
* @param string $temp_filename
|
|
* @param string $outputformat
|
|
* @param string $user Must be a valid uid
|
|
* @param string $profile Signatureprofile for signing
|
|
*
|
|
* @return stdClass
|
|
*/
|
|
protected function sign($temp_folder, $temp_filename, $outputformat, $user, $profile)
|
|
{
|
|
if ($outputformat != 'pdf')
|
|
return error($this->ci->documentExportPhrases->t("document_export", "error_sign_pdf"));
|
|
|
|
// Load the File
|
|
$file_data = file_get_contents($temp_filename);
|
|
|
|
$data = new stdClass();
|
|
$data->document = base64_encode($file_data);
|
|
|
|
// Signatur Profil
|
|
if (!is_null($profile))
|
|
$data->profile = $profile;
|
|
else
|
|
$data->profile = SIGNATUR_DEFAULT_PROFILE;
|
|
|
|
// Username des Endusers der die Signatur angefordert hat
|
|
$data->user = $user;
|
|
|
|
$ch = curl_init();
|
|
|
|
curl_setopt($ch, CURLOPT_URL, SIGNATUR_URL . '/' . SIGNATUR_SIGN_API);
|
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7);
|
|
curl_setopt($ch, CURLOPT_USERAGENT, "FH-Complete");
|
|
|
|
// SSL Zertifikatsprüfung deaktivieren
|
|
// Besser ist es das Zertifikat am Server zu installieren!
|
|
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
|
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
|
$data_string = json_encode($data, JSON_FORCE_OBJECT);
|
|
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
'Content-Type: application/json',
|
|
'Content-Length:' . mb_strlen($data_string),
|
|
'Authorization: Basic ' . base64_encode(SIGNATUR_USER . ":" . SIGNATUR_PASSWORD)
|
|
]);
|
|
|
|
$result = curl_exec($ch);
|
|
if (curl_errno($ch)) {
|
|
curl_close($ch);
|
|
return error($this->ci->documentExportPhrases->t("document_export", "error_sign_timeout"));
|
|
}
|
|
curl_close($ch);
|
|
$resultdata = json_decode($result);
|
|
|
|
// If it is success
|
|
if (isset($resultdata->error) && $resultdata->error == 0) {
|
|
$signed_filename = $temp_folder . '/signed.pdf';
|
|
file_put_contents($signed_filename, base64_decode($resultdata->retval));
|
|
return success($signed_filename);
|
|
}
|
|
|
|
// otherwise if it is an error
|
|
return error($resultdata->retval ?? $this->ci->documentExportPhrases->t("global", "unknown_error", ["error" => $result]));
|
|
}
|
|
|
|
/**
|
|
* Deletes all files in the $temp_folder and changes back to the source_folder
|
|
*
|
|
* @param string $temp_folder
|
|
* @param string $source_folder
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function close($temp_folder, $source_folder)
|
|
{
|
|
$files = glob($temp_folder . '/*'); // get all file names
|
|
foreach ($files as $file)
|
|
if (is_file($file))
|
|
unlink($file);
|
|
|
|
chdir($source_folder);
|
|
rmdir($temp_folder);
|
|
}
|
|
|
|
/**
|
|
* Convert an array to XML
|
|
*
|
|
* @param array $data
|
|
* @param string $root
|
|
* @param SimpleXMLElement $xml_data
|
|
*
|
|
* @return string|boolean
|
|
*/
|
|
private function convertArrayToXML($data, $root = null, $xml_data = null)
|
|
{
|
|
$_xml_data = $xml_data;
|
|
if ($_xml_data === null)
|
|
$_xml_data = new SimpleXMLElement($root !== null ? '<' . $root . ' />' : '<root/>');
|
|
|
|
foreach ($data as $key => $value) {
|
|
if (is_array($value)) {
|
|
if (is_numeric($key)) {
|
|
$key = 'item' . $key; // dealing with <0/>..<n/> issues
|
|
$this->convertArrayToXML($value, null, $_xml_data);
|
|
} else {
|
|
$subnode = $_xml_data->addChild($key);
|
|
$this->convertArrayToXML($value, null, $subnode);
|
|
}
|
|
} else {
|
|
// Remove UTF8 Control Characters (breaking XML)
|
|
$value = preg_replace('/[\x00-\x1F\x7F]/u', '', $value);
|
|
$_xml_data->addChild((string)$key, htmlspecialchars("$value"));
|
|
}
|
|
}
|
|
|
|
return $_xml_data->asXML();
|
|
}
|
|
|
|
/**
|
|
* Get default outputformat from mimetype if its not set
|
|
*
|
|
* @param string $outputformat
|
|
* @param string $mimetype
|
|
*
|
|
* @return string
|
|
*/
|
|
private function getDefaultOutputFormat($outputformat, $mimetype)
|
|
{
|
|
if ($outputformat)
|
|
return $outputformat;
|
|
|
|
if ($mimetype == 'application/vnd.oasis.opendocument.spreadsheet')
|
|
return 'ods';
|
|
if ($mimetype == 'application/vnd.oasis.opendocument.text')
|
|
return 'odt';
|
|
|
|
return 'pdf';
|
|
}
|
|
}
|