Skip to content
Snippets Groups Projects
Commit 861f45e9 authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Pb colier/coller de fichier!!

parent d9fd6f7a
No related branches found
No related tags found
No related merge requests found
......@@ -2,107 +2,196 @@
namespace Unicaen\OpenDocument;
use Exception;
use DOMDocument;
use DOMElement;
use DOMNode;
use DOMNodeList;
use Exception;
use ZipArchive;
class Publisher
class Document
{
const PAGE_BREAK_NAME = 'UNICAEN_PAGE_BREAK';
const PARAGRAPH = 'text:p';
const TABLE_ROW = 'table:table-row';
/**
* @var ZipArchive
*/
private $archive;
/**
* Lecteur de fichier OpenDocument
*
* @var Document
* @var bool
*/
private $document;
private $pdfOutput = false;
/**
* @var Publisher
*/
private $publisher;
/**
* @var Stylist
*/
private $stylist;
/**
* @var DomDocument;
*/
private $meta;
/**
* @var DOMDocument
*/
private $styles;
/**
* Contenu XML du corps de texte
*
* @var DOMDocument
*/
private $content;
/**
* @var DOMElement
* @var array
*/
private $body;
private $namespaces = [];
/**
* Ajoute un saut de page automatiquement entre deux instances de document lors du publipostage
*
* @var boolean
* @var bool
*/
private $autoBreak = true;
private $metaChanged = false;
/**
* @var array
* @var bool
*/
private $values = [];
private $stylesChanged = false;
/**
* @var bool
*/
private $contentChanged = false;
/**
* Variable contenant le résultat final du content.xml
*
* @var string
*/
private $outContent;
private $convCommand = 'unoconv -f pdf -o :outputFile :inputFile';
/**
* @var bool
* @var string
*/
private $published = false;
private $tmpDir;
/**
* @var array
*/
private $formatters = [];
/**
* @return Document
* @var array
*/
public function getDocument(): Document
private $tmpFiles = [];
private $defaultNamespaces = [
'office' => "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
'style' => "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
'text' => "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
'table' => "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
'draw' => "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
'fo' => "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
'xlink' => "http://www.w3.org/1999/xlink",
'dc' => "http://purl.org/dc/elements/1.1/",
'meta' => "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
'number' => "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
'svg' => "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
'chart' => "urn:oasis:names:tc:opendocument:xmlns:chart:1.0",
'dr3d' => "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",
'math' => "http://www.w3.org/1998/Math/MathML",
'form' => "urn:oasis:names:tc:opendocument:xmlns:form:1.0",
'script' => "urn:oasis:names:tc:opendocument:xmlns:script:1.0",
'ooo' => "http://openoffice.org/2004/office",
'ooow' => "http://openoffice.org/2004/writer",
'oooc' => "http://openoffice.org/2004/calc",
'dom' => "http://www.w3.org/2001/xml-events",
'rpt' => "http://openoffice.org/2005/report",
'of' => "urn:oasis:names:tc:opendocument:xmlns:of:1.2",
'xhtml' => "http://www.w3.org/1999/xhtml",
'grddl' => "http://www.w3.org/2003/g/data-view#",
'officeooo' => "http://openoffice.org/2009/office",
'tableooo' => "http://openoffice.org/2009/table",
'drawooo' => "http://openoffice.org/2010/draw",
'calcext' => "urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0",
'css3t' => "http://www.w3.org/TR/css3-text/",
'xforms' => 'http://www.w3.org/2002/xforms',
'xsd' => 'http://www.w3.org/2001/XMLSchema',
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'loext' => 'urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0',
'field' => 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0',
'formx' => 'urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0',
];
/**
* @return ZipArchive
* @throws Exception
*/
public function getArchive(): ZipArchive
{
return $this->document;
if (!$this->archive) {
throw new \Exception("Aucun document n\'est chargé");
}
return $this->archive;
}
/**
* @param Document $document
*
* @return Publisher
* @return DOMDocument
*/
public function setDocument(Document $document): Publisher
public function getContent(): DOMDocument
{
$this->document = $document;
return $this->content;
}
return $this;
/**
* @return DOMDocument
*/
public function getStyles(): DOMDocument
{
return $this->styles;
}
/**
* @return DOMElement
* @return DOMDocument
*/
public function getBody(): DOMElement
public function getMeta(): DOMDocument
{
return $this->body;
return $this->meta;
}
/**
* Peuple l'instance courante du document et l'ajoute à la suite du fichier
* @return bool
*/
public function isPdfOutput(): bool
{
return $this->pdfOutput;
}
/**
* @param bool $pdfOutput
*
* @param array $values
* @return Document
*/
public function add(array $values): Publisher
public function setPdfOutput(bool $pdfOutput): Document
{
$this->values[] = $values;
$this->pdfOutput = $pdfOutput;
return $this;
}
......@@ -110,21 +199,23 @@ class Publisher
/**
* @return array
* @return bool
*/
public function getValues(): array
public function isMetaChanged(): bool
{
return $this->values;
return $this->metaChanged;
}
/**
* @param array $values
* @param bool $metaChanged
*
* @return Document
*/
public function setValues(array $values): Publisher
public function setMetaChanged(bool $metaChanged): Document
{
$this->values = $values;
$this->metaChanged = $metaChanged;
return $this;
}
......@@ -134,21 +225,21 @@ class Publisher
/**
* @return bool
*/
public function isAutoBreak(): bool
public function isStylesChanged(): bool
{
return $this->autoBreak;
return $this->stylesChanged;
}
/**
* @param bool $autoBreak
* @param bool $stylesChanged
*
* @return Publisher
* @return Document
*/
public function setAutoBreak(bool $autoBreak): Publisher
public function setStylesChanged(bool $stylesChanged): Document
{
$this->autoBreak = $autoBreak;
$this->stylesChanged = $stylesChanged;
return $this;
}
......@@ -156,167 +247,265 @@ class Publisher
/**
* @param DOMElement $element
*
* @return Publisher
* @throws Exception
* @return bool
*/
public function getVariables(DOMElement $element): array
public function isContentChanged(): bool
{
$textNs = $this->getDocument()->getNamespaceUrl('text');
return $this->contentChanged;
}
$variables = [];
$vElements = $element->getElementsByTagNameNS($textNs, 'variable-set');
foreach ($vElements as $vElement) {
$name = $vElement->getAttributeNS($textNs, 'name');
/**
* @param bool $contentChanged
*
* @return Document
*/
public function setContentChanged(bool $contentChanged): Document
{
$this->contentChanged = $contentChanged;
if (!isset($variables[$name])) $variables[$name] = [];
$variables[$name][] = $vElement;
return $this;
}
return $variables;
/**
* @return string
*/
public function getConvCommand(): string
{
return $this->convCommand;
}
public function getSections(DOMElement $element): array
/**
* @param string $convCommand
*
* @return Document
*/
public function setConvCommand(string $convCommand): Document
{
$textNs = $this->getDocument()->getNamespaceUrl('text');
$this->convCommand = $convCommand;
return $this;
}
$sections = [];
$vElements = $this->findFrom($element, 'text:section');
foreach ($vElements as $vElement) {
$name = $vElement->getAttributeNS($textNs, 'name');
if (!isset($sections[$name])) $sections[$name] = [];
$sections[$name][] = $vElement;
/**
* Retourne les méta-données du fichier OpenDocument
*
* @return array
*/
public function getMetaArray(): array
{
$m = [];
$nodes = $this->getMeta()->documentElement->childNodes->item(0)->childNodes;
foreach ($nodes as $node) {
if (isset($node->tagName)) {
switch ($node->tagName) {
case 'meta:generator':
case 'meta:initial-creator':
case 'meta:editing-cycles':
case 'meta:editing-duration':
case 'meta:printed-by':
case 'dc:title':
case 'dc:description':
case 'dc:subject':
case 'dc:creator':
case 'dc:language':
list($ns, $tag) = explode(':', $node->tagName);
$m[$tag] = $node->textContent;
break;
case 'meta:creation-date':
$m['creation-date'] = substr($node->textContent, 0, 10);
break;
case 'meta:print_date':
$m['print_date'] = substr($node->textContent, 0, 10);
break;
case 'dc:date':
$m['date'] = substr($node->textContent, 0, 10);
break;
case 'meta:document-statistic':
$m['document-statistic'] = [];
foreach ($node->attributes as $attribute) {
$m['document-statistic'][$attribute->name] = $attribute->value;
}
break;
case 'meta:user-defined':
if (!isset($m['user-defined'])) $m['user-defined'] = [];
foreach ($node->attributes as $attribute) {
$m['user-defined'][$attribute->name] = $attribute->value;
}
break;
case 'meta:keywords':
$m['keywords'] = [];
foreach ($node->childNodes as $knode) {
$m['keywords'][] = $knode->textContent;
}
break;
}
}
}
return $sections;
return $m;
}
public function hideSection(DOMElement $section): Publisher
/**
* @param string $variable
* @param mixed $value
*
* @return string
*/
public function formatValue(string $variable, $value): string
{
$section->parentNode->removeChild($section);
if (isset($this->formatters[$variable]) && $format = $this->formatters[$variable]){
if (is_callable($format)){
$value = $format($value);
}
}
return $this;
if (is_float($value)){
return number_format($value, 2, ',', ' ');
}
return (string)$value;
}
/**
* @param DOMElement $element
* @param mixed $value
* Retourne les espaces de nom associés à leurs URI respectives sous forme de tableau associatif
*
* @return Publisher
* @return array
*/
protected function setVariable(DOMElement $element, $value): Publisher
public function getNamespaces(): array
{
$textNs = $this->getDocument()->getNamespaceUrl('text');
$document = $element->ownerDocument;
if (empty($this->namespaces)) {
$content = $this->getArchive()->getFromName('content.xml');
if (is_string($value) && false !== strpos($value, "\n")){
$value = explode("\n", $value);
}else{
$value = (array)$value;
$begin = strpos($content, '<', 1) + 2 + strlen('office:document-content');
$end = strpos($content, '>', 50) - $begin;
$content = explode(' ', substr($content, $begin, $end));
$this->namespaces = $this->defaultNamespaces;
foreach ($content as $str) {
if (0 === strpos($str, 'xmlns:')) {
$namespace = substr($str, 6, strpos($str, '"') - 7);
$url = substr($str, strpos($str, '"') + 1, -1);
$this->namespaces[$namespace] = $url;
}
for ($i = 0; $i < count($value); $i++) {
if ($i > 0) {
$returnVNode = $document->createElementNS($textNs, 'text:line-break');
$element->parentNode->insertBefore($returnVNode, $element);
}
$vText = $document->createTextNode($this->getDocument()->formatValue($element->nodeValue,$value[$i]));
$element->parentNode->insertBefore($vText, $element);
}
$element->parentNode->removeChild($element);
return $this;
return $this->namespaces;
}
private function addPageBreakStyle(): Publisher
/**
* @param string $name
*
* @return bool
*/
public function hasNamespace(string $name): bool
{
/* get office:automatic-styles node */
$styles = $this->content->getElementsByTagNameNS(
$this->getDocument()->getNamespaceUrl('office'),
'automatic-styles'
)->item(0);
$this->getNamespaces();
return isset($this->namespaces[$name]);
}
$stylePageBreak = $this->newElement('style:style', [
'style:name' => self::PAGE_BREAK_NAME,
'style:family' => 'paragraph',
'style:parent-style-name' => 'Standard',
'style:master-page-name' => 'Standard',
]);
$stylePageBreakProperties = $this->newElement('style:paragraph-properties', [
'style:writing-mode' => 'page',
'style:page-number' => '1',
]);
$stylePageBreak->appendChild($stylePageBreakProperties);
$styles->appendChild($stylePageBreak);
/**
* @param string $name
* @param string $url
*
* @return Document
*/
public function addNamespace(string $name, string $url): Document
{
if (!$this->hasNamespace($name)) {
$this->namespaces[$name] = $url;
}
return $this;
}
private function addPageBreak(DOMElement $element): Publisher
/**
* Retourne l'url associé à un espace de nom
*
* @param string $namespace
*
* @return string
*/
public function getNamespaceUrl(string $namespace): string
{
$textNs = $this->getDocument()->getNamespaceUrl('text');
$ns = $this->getNamespaces();
$pageBreak = $this->content->createElementNS($textNs, 'text:p');
$pageBreak->setAttributeNS($textNs, 'text:style-name', self::PAGE_BREAK_NAME);
$element->insertBefore($pageBreak, $element->firstChild);
if (!isset($ns[$namespace])) {
throw new Exception('L\'espace de nom ' . $namespace . ' n\'a pas été trouvé.');
}
return $this;
return $ns[$namespace];
}
/**
* @return Publisher
* @throws Exception
* Retourne un champ d'information
*
* @param integer $index
*
* @return string
*/
public function publishBegin(): Publisher
public function getInfo($index)
{
/* On récupère le content du document */
$this->content = new DOMDocument();
$this->content->loadXML($this->getDocument()->getContent()->saveXML());
$infonodes = $this->getMeta()->getElementsByTagNameNS($this->getNamespaceUrl('meta'), 'user-defined');
if ($this->isAutoBreak()) {
$this->addPageBreakStyle();
return $infonodes->item($index)->nodeValue;
}
$contentText = $this->content->saveXML();
$officeDocumentContentPos = strpos($contentText, '<office:document-content');
$length = strpos($contentText, '>', $officeDocumentContentPos) + 1;
$this->out(substr($contentText, 0, $length));
/* wtite all nodes, except body */
foreach ($this->content->documentElement->childNodes as $node) {
if ($node->nodeName != 'office:body') {
$this->out($this->content->saveXML($node));
}
}
$this->out("<office:body>");
/* declaration tags */
$declTags = [
'variable-decls', 'sequence-decls', 'user-field-decls', 'dde-connexion-decls',
];
foreach ($declTags as $tagName) {
$node = $this->content->getElementsByTagNameNS($this->getDocument()->getNamespaceUrl('text'), $tagName);
if ($node->length > 0) {
$this->out($this->content->saveXML($node->item(0)));
$node->item(0)->parentNode->removeChild($node->item(0));
/**
* Modifie un champ d'information
*
* @todo à finir d'implémenter, car ça ne marche pas!!
*
* @param integer $index
* @param string $value
*/
public function setInfo($index, $value): Document
{
throw new \Exception('Implémentation à corriger : ne fonctionne pas');
$infonodes = $this->getMeta()->getElementsByTagNameNS($this->getNamespaceUrl('meta'), 'user-defined');
if ($infonodes->length > 0) {
$infonodes->item($index)->nodeValue = $value;
$this->setMetaChanged(true);
}
return $this;
}
$this->body = $this->content->getElementsByTagNameNS($this->getDocument()->getNamespaceUrl('office'), 'text')[0];
/**
* @param array $values
*
* @return Document
*/
public function publish(array $values): Document
{
$this->getPublisher()->setValues($values);
$this->getPublisher()->publish();
return $this;
}
......@@ -326,114 +515,167 @@ class Publisher
/**
* @return Publisher
*/
public function publishEnd(): Publisher
public function getPublisher(): Publisher
{
$this->out("</office:body></office:document-content>");
if (!$this->publisher) {
$this->publisher = new Publisher();
$this->publisher->setDocument($this);
}
/* On renvoie le content dans le document */
$this->getDocument()->getArchive()->addFromString('content.xml', $this->outContent);
$this->published = true;
return $this->publisher;
}
return $this;
/**
* @return Stylist
*/
public function getStylist(): Stylist
{
if (!$this->stylist) {
$this->stylist = new Stylist();
$this->stylist->setDocument($this);
}
return $this->stylist;
}
/**
* @param DOMElement $element
* @param array $values
* @param $data
*
* @return Publisher
* @return Document
* @throws Exception
*/
public function publishValues(DOMElement $element, array $values): Publisher
public function loadFromData($data): Document
{
if ($element === $this->body) {
$this->getDocument()->getStylist()->setVariables($values);
if (!class_exists('ZipArchive')) {
throw new Exception('Zip extension not loaded');
}
$variables = $this->getVariables($element);
$sections = $this->getSections($element);
$odtFile = $this->tempFileName('odtfile_', 'odt');
file_put_contents($odtFile, $data);
foreach ($values as $name => $val) {
if (is_array($val)) {
/* On traite les données filles... */
list($vname, $vparent) = explode("@", $name);
if (isset($variables[$vname])) {
foreach ($variables[$vname] as $elVar) {
$this->publishSubData($elVar, $vparent, $val);
return $this->loadFromFile($odtFile, false);
}
/**
* @param string $fileName
* @param bool $duplicate
*
* @return Document
* @throws Exception
*/
public function loadFromFile(string $fileName, bool $duplicate = true): Document
{
if (!class_exists('ZipArchive')) {
throw new Exception('Zip extension not loaded');
}
if (isset($sections[$vname])) {
foreach ($sections[$vname] as $elSec) {
$this->publishSubData($elSec, $vparent, $val);
}
if (!file_exists($fileName)) {
throw new Exception('OpenDocument file "' . $fileName . '" doesn\'t exists.');
}
if ($duplicate) {
$odtFile = $this->tempFileName('odtFile_', 'odt');
copy($fileName, $odtFile);
} else {
if (isset($variables[$name])) {
foreach ($variables[$name] as $vElement) {
$this->setVariable($vElement, $val ? $val : '');
}
}
if (false !== strpos($name, '@')) {
list($sName, $sType) = explode("@", $name);
if ($sType == 'text:section') {
$name = $sName;
$odtFile = $fileName;
}
$this->archive = new ZipArchive();
if (!true === $this->archive->open($odtFile, ZIPARCHIVE::CREATE)) {
throw new Exception('OpenDocument file "' . $fileName . '" don\'t readable.');
}
if (isset($sections[$name])) {
foreach ($sections[$name] as $sElement) {
if ($val === null
|| $val === 0
|| $val === '0'
|| $val === false
|| $val === ''
|| strtolower($val) === 'false'
) {
$this->hideSection($sElement);
$this->meta = new DOMDocument;
$this->meta->loadXML($this->archive->getFromName('meta.xml'));
$this->styles = new DOMDocument;
$this->styles->loadXML($this->archive->getFromName('styles.xml'));
$this->content = new DOMDocument;
$this->content->loadXML($this->archive->getFromName('content.xml'));
$this->namespaces = [];
return $this;
}
/**
* @return string
* @throws Exception
*/
private function prepareSaving($filename = null): string
{
if ($this->isMetaChanged()) {
$this->getArchive()->addFromString('meta.xml', $this->getMeta()->saveXML());
}
if ($this->isStylesChanged()) {
$this->getArchive()->addFromString('styles.xml', $this->getStyles()->saveXML());
}
if ($this->isContentChanged()) {
$this->getArchive()->addFromString('content.xml', $this->getContent()->saveXML());
}
$actualFile = $this->getArchive()->filename;
$this->getArchive()->close();
$this->archive = null;
if ($this->isPdfOutput()) {
if (!$filename) {
$filename = $this->tempFileName('odt2pdf_', 'pdf');
}
if ($element === $this->body) {
$this->out($this->content->saveXML($element));
$this->odtToPdf($actualFile, $filename);
$actualFile = $filename;
}
return $this;
return $actualFile;
}
/**
* @param DOMElement $element
* @param string $parent
* @param string $variable
* @param $origine
* @param $destination
*
* @return DOMElement
* @return Document
* @throws Exception
*/
public function getSubDoc(DOMElement $element, string $parent, string $variable): DOMElement
public function odtToPdf($origine, $destination): Document
{
$variables = $this->getVariables($element);
if (!isset($variables[$variable][0])) {
throw new \Exception('La variable "' . $variable . '"" n\'a pas été trouvée dans le document');
$command = $this->getConvCommand();
$command = str_replace(':inputFile', $origine, $this->getConvCommand());
$command = str_replace(':outputFile', $destination, $command);
exec($command, $output, $return);
if (0 != $return) {
throw new \Exception('La conversion de document en PDF a échoué');
}
return $this->getSubDocWithVariable($variables[$variable][0], $parent);
return $this;
}
/**
* @param DOMElement $element
* @param string $fileName
*
* @return Publisher
* @return Document
* @throws Exception
*/
public function remove(DOMElement $element): Publisher
public function saveToFile(string $fileName): Document
{
$element->parentNode->removeChild($element);
$actualFile = $this->prepareSaving($fileName);
return $this;
}
......@@ -441,192 +683,186 @@ class Publisher
/**
* @param DOMElement $subDoc
* @param array $variables
* @param DOMElement $refNode
*
* @return Publisher
* @return string
* @throws Exception
*/
public function publishBefore(DOMElement $subDoc, array $variables, DOMElement $refNode): Publisher
public function saveToData(): string
{
$node = $subDoc->cloneNode(true);
$this->publishValues($node, $variables);
$refNode->parentNode->insertBefore($node, $refNode);
$actualFile = $this->prepareSaving();
return $this;
return file_get_contents($actualFile);
}
/**
* @param DOMElement $element
* @param string $parent
* @param DOMElement $variable
*
* @return DOMElement
* @throws Exception
* @return string
*/
private function getSubDocWithVariable(DOMElement $element, string $parent): DOMElement
public function getTmpDir(): string
{
if ($element->tagName == 'text:section') {
return $element; // C'est la section qui est dupliquée
} else {
$i = 10;
$found = false;
for ($i = 0; $i < 10; $i++) {
$parentNode = isset($parentNode) ? $parentNode->parentNode : $element->parentNode;
if ($parentNode->nodeName == $parent) {
$found = true;
break;
}
if (!$this->tmpDir) {
return sys_get_temp_dir();
}
if (!$found) {
throw new \Exception('Le noeud parent de type ' . $parent . ' n\'a pas été trouvé');
}
return $parentNode;
}
return $this->tmpDir;
}
/**
* @param DOMElement $element
* @param string $parent
* @param array $values
* @param string $tmpDir
*
* @return Publisher
* @return Document
*/
private function publishSubData(DOMElement $element, string $parent, array $values): Publisher
public function setTmpDir(string $tmpDir): Document
{
$parentNode = $this->getSubDocWithVariable($element, $parent);
foreach ($values as $vals) {
$clone = $parentNode->cloneNode(true);
$this->publishValues($clone, $vals);
$parentNode->parentNode->insertBefore($clone, $parentNode);
$this->tmpDir = $tmpDir;
if (!file_exists($tmpDir)) {
mkdir($tmpDir);
}
return $this->remove($parentNode);
return $this;
}
/**
* Construit le fichier final à partir des données
* @param null $prefix
*
* @return string
*/
public function publish()
private function tempFileName($prefix = null, $ext = 'odt'): string
{
$this->publishBegin();
$first = true;
foreach ($this->values as $values) {
$bodyNode = $this->body->cloneNode(true);
if ($first) {
$first = false;
} elseif ($this->isAutoBreak()) {
$this->addPageBreak($bodyNode);
$tmpDir = $this->getTmpDir();
if ('/' != substr($tmpDir, -1)) {
$tmpDir .= '/';
}
$this->publishValues($bodyNode, $values);
$this->getDocument()->getStylist()->setVariables($values);
$this->out($this->content->saveXML($bodyNode));
$first = false;
}
$tempFileName = uniqid($tmpDir . $prefix) . '.' . $ext;
$this->tmpFiles[] = $tempFileName;
$this->publishEnd();
return $tempFileName;
}
/**
* @param string $name
*
* @return DOMNode[]
* @throws Exception
* @return array
*/
private function find(string $name): DOMNodeList
public function getFormatters(): array
{
$document = $this->getDocument();
return $document->find($this->content, $name);
return $this->formatters;
}
/**
* @param DOMNode $node
* @param $name
* @param string $variable
* @param mixed $format
*
* @return DOMNodeList
* @throws Exception
* @return Document
*/
private function findFrom(DOMNode $node, $name): DOMNodeList
public function addFormatter(string $variable, $format): Document
{
return $this->getDocument()->find($node, $name);
$this->formatters[$variable] = $format;
return $this;
}
/**
* @param string $name
* @param array $attrs
* PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++.
* The destructor method will be called as soon as all references to a particular object are removed or
* when the object is explicitly destroyed or in any order in shutdown sequence.
*
* @return DOMElement
* Like constructors, parent destructors will not be called implicitly by the engine.
* In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body.
*
* Note: Destructors called during the script shutdown have HTTP headers already sent.
* The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache).
*
* Note: Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal
* error.
*
* @return void
* @link https://php.net/manual/en/language.oop5.decon.php
*/
private function newElement(string $name, array $attrs = []): DOMElement
public function __destruct()
{
$document = $this->getDocument();
return $document->newElement($this->content, $name, $attrs);
/* On supprime les éventuels fichiers temporaires pour libérer l'espace */
foreach ($this->tmpFiles as $tmpFile) {
if (file_exists($tmpFile)) {
unlink($tmpFile);
}
}
}
/**
* Ajoute du contenu au fichier content.xml
* Méthode à ne pas exploiter
* @param $fileName
*
* @param string $xml
* @return Document
* @throws Exception
*/
public function out($xml)
public function download($fileName): Document
{
$this->outContent .= $xml;
$actualFile = $this->prepareSaving();
if (headers_sent()) {
throw new Exception('Headers Allready Sent');
}
$contentType = $this->isPdfOutput() ? 'application/pdf' : 'application/vnd.oasis.opendocument.text';
header('Content-type: ' . $contentType);
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Transfer-Encoding: binary');
header('Pragma: no-cache');
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
readfile($actualFile);
/**
* @return string
*/
public function getOutContent(): string
{
return $this->outContent;
return $this;
}
/**
* @return bool
* @param DOMNode $node
* @param string $name
*
* @return DOMNode[]
* @throws Exception
*/
public function isPublished(): bool
public function find(DOMNode $node, string $name): DOMNodeList
{
return $this->published;
list($namespace, $name) = explode(':', $name);
return $node->getElementsByTagNameNS($this->getNamespaceUrl($namespace), $name);
}
/**
* @param bool $published
* @param DOMDocument $document
* @param string $name
* @param array $attrs
*
* @return Publisher
* @return DOMElement
* @throws Exception
*/
public function setPublished(bool $published): Publisher
public function newElement(DOMDocument $document, string $name, array $attrs = []): DOMElement
{
$this->published = $published;
list($namespace) = explode(':', $name);
return $this;
$newNode = $document->createElementNS($this->getNamespaceUrl($namespace), $name);
foreach ($attrs as $attrName => $attrValue) {
list($attrNS) = explode(':', $attrName);
$newNode->setAttributeNS($this->getNamespaceUrl($attrNS), $attrName, $attrValue);
}
return $newNode;
}
}
......@@ -505,7 +505,7 @@ class Publisher
foreach ($values as $vals) {
$clone = $parentNode->cloneNode(true);
$this->publishValues($clone, $vals);
$this->insertBefore($clone, $parentNode);
$parentNode->parentNode->insertBefore($clone, $parentNode);
}
return $this->remove($parentNode);
......@@ -530,6 +530,7 @@ class Publisher
}
$this->publishValues($bodyNode, $values);
$this->getDocument()->getStylist()->setVariables($values);
$this->out($this->content->saveXML($bodyNode));
$first = false;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment