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

Possibilité de formatter les variables OpenDocument avec des fonctions PHP

Possibilités de contrôle étendu des documents
parent b9716014
No related branches found
No related tags found
No related merge requests found
...@@ -78,6 +78,12 @@ class Document ...@@ -78,6 +78,12 @@ class Document
*/ */
private $tmpDir; private $tmpDir;
/**
* @var array
*/
private $formatters = [];
/** /**
* @var array * @var array
*/ */
...@@ -350,6 +356,29 @@ class Document ...@@ -350,6 +356,29 @@ class Document
/**
* @param string $variable
* @param mixed $value
*
* @return string
*/
public function formatValue(string $variable, $value): string
{
if (isset($this->formatters[$variable]) && $format = $this->formatters[$variable]){
if (is_callable($format)){
$value = $format($value);
}
}
if (is_float($value)){
return number_format($value, 2, ',', ' ');
}
return (string)$value;
}
/** /**
* Retourne les espaces de nom associés à leurs URI respectives sous forme de tableau associatif * Retourne les espaces de nom associés à leurs URI respectives sous forme de tableau associatif
* *
...@@ -717,6 +746,31 @@ class Document ...@@ -717,6 +746,31 @@ class Document
/**
* @return array
*/
public function getFormatters(): array
{
return $this->formatters;
}
/**
* @param string $variable
* @param mixed $format
*
* @return Document
*/
public function addFormatter(string $variable, $format): Document
{
$this->formatters[$variable] = $format;
return $this;
}
/** /**
* PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. * 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 * The destructor method will be called as soon as all references to a particular object are removed or
......
...@@ -13,6 +13,9 @@ class Publisher ...@@ -13,6 +13,9 @@ class Publisher
{ {
const PAGE_BREAK_NAME = 'UNICAEN_PAGE_BREAK'; const PAGE_BREAK_NAME = 'UNICAEN_PAGE_BREAK';
const PARAGRAPH = 'text:p';
const TABLE_ROW = 'table:table-row';
/** /**
* Lecteur de fichier OpenDocument * Lecteur de fichier OpenDocument
* *
...@@ -51,6 +54,11 @@ class Publisher ...@@ -51,6 +54,11 @@ class Publisher
*/ */
private $outContent; private $outContent;
/**
* @var bool
*/
private $published = false;
/** /**
...@@ -77,6 +85,16 @@ class Publisher ...@@ -77,6 +85,16 @@ class Publisher
/**
* @return DOMElement
*/
public function getBody(): DOMElement
{
return $this->body;
}
/** /**
* Peuple l'instance courante du document et l'ajoute à la suite du fichier * Peuple l'instance courante du document et l'ajoute à la suite du fichier
* *
...@@ -161,10 +179,6 @@ class Publisher ...@@ -161,10 +179,6 @@ class Publisher
public function getSections(DOMElement $element): array public function getSections(DOMElement $element): array
{ {
$textNs = $this->getDocument()->getNamespaceUrl('text'); $textNs = $this->getDocument()->getNamespaceUrl('text');
...@@ -194,23 +208,26 @@ class Publisher ...@@ -194,23 +208,26 @@ class Publisher
/** /**
* @param DOMElement $element * @param DOMElement $element
* @param string $value * @param mixed $value
* *
* @return Publisher * @return Publisher
*/ */
public function setVariable(DOMElement $element, string $value): Publisher protected function setVariable(DOMElement $element, $value): Publisher
{ {
$textNs = $this->getDocument()->getNamespaceUrl('text'); $textNs = $this->getDocument()->getNamespaceUrl('text');
$document = $element->ownerDocument; $document = $element->ownerDocument;
if (is_string($value) && false !== strpos($value, "\n")){
$value = explode("\n", $value); $value = explode("\n", $value);
}else{
$value = (array)$value;
}
for ($i = 0; $i < count($value); $i++) { for ($i = 0; $i < count($value); $i++) {
if ($i > 0) { if ($i > 0) {
$returnVNode = $document->createElementNS($textNs, 'text:line-break'); $returnVNode = $document->createElementNS($textNs, 'text:line-break');
$element->parentNode->insertBefore($returnVNode, $element); $element->parentNode->insertBefore($returnVNode, $element);
} }
$vText = $document->createTextNode($value[$i]); $vText = $document->createTextNode($this->getDocument()->formatValue($element->nodeValue,$value[$i]));
$element->parentNode->insertBefore($vText, $element); $element->parentNode->insertBefore($vText, $element);
} }
$element->parentNode->removeChild($element); $element->parentNode->removeChild($element);
...@@ -264,8 +281,16 @@ class Publisher ...@@ -264,8 +281,16 @@ class Publisher
* @return Publisher * @return Publisher
* @throws Exception * @throws Exception
*/ */
private function publishBegin(): Publisher public function publishBegin(): Publisher
{ {
/* On récupère le content du document */
$this->content = new DOMDocument();
$this->content->loadXML($this->getDocument()->getContent()->saveXML());
if ($this->isAutoBreak()) {
$this->addPageBreakStyle();
}
$contentText = $this->content->saveXML(); $contentText = $this->content->saveXML();
$officeDocumentContentPos = strpos($contentText, '<office:document-content'); $officeDocumentContentPos = strpos($contentText, '<office:document-content');
$length = strpos($contentText, '>', $officeDocumentContentPos) + 1; $length = strpos($contentText, '>', $officeDocumentContentPos) + 1;
...@@ -291,6 +316,8 @@ class Publisher ...@@ -291,6 +316,8 @@ class Publisher
} }
} }
$this->body = $this->content->getElementsByTagNameNS($this->getDocument()->getNamespaceUrl('office'), 'text')[0];
return $this; return $this;
} }
...@@ -299,10 +326,14 @@ class Publisher ...@@ -299,10 +326,14 @@ class Publisher
/** /**
* @return Publisher * @return Publisher
*/ */
private function publishEnd(): Publisher public function publishEnd(): Publisher
{ {
$this->out("</office:body></office:document-content>"); $this->out("</office:body></office:document-content>");
/* On renvoie le content dans le document */
$this->getDocument()->getArchive()->addFromString('content.xml', $this->outContent);
$this->published = true;
return $this; return $this;
} }
...@@ -315,8 +346,12 @@ class Publisher ...@@ -315,8 +346,12 @@ class Publisher
* @return Publisher * @return Publisher
* @throws Exception * @throws Exception
*/ */
private function publishValues(DOMElement $element, array $values): Publisher public function publishValues(DOMElement $element, array $values): Publisher
{ {
if ($element === $this->body) {
$this->getDocument()->getStylist()->setVariables($values);
}
$variables = $this->getVariables($element); $variables = $this->getVariables($element);
$sections = $this->getSections($element); $sections = $this->getSections($element);
...@@ -362,6 +397,10 @@ class Publisher ...@@ -362,6 +397,10 @@ class Publisher
} }
} }
if ($element === $this->body) {
$this->out($this->content->saveXML($element));
}
return $this; return $this;
} }
...@@ -370,14 +409,67 @@ class Publisher ...@@ -370,14 +409,67 @@ class Publisher
/** /**
* @param DOMElement $element * @param DOMElement $element
* @param string $parent * @param string $parent
* @param array $values * @param string $variable
*
* @return DOMElement
* @throws Exception
*/
public function getSubDoc(DOMElement $element, string $parent, string $variable): DOMElement
{
$variables = $this->getVariables($element);
if (!isset($variables[$variable][0])) {
throw new \Exception('La variable "' . $variable . '"" n\'a pas été trouvée dans le document');
}
return $this->getSubDocWithVariable($variables[$variable][0], $parent);
}
/**
* @param DOMElement $element
* *
* @return Publisher * @return Publisher
*/ */
private function publishSubData(DOMElement $element, string $parent, array $values): Publisher public function remove(DOMElement $element): Publisher
{
$element->parentNode->removeChild($element);
return $this;
}
/**
* @param DOMElement $subDoc
* @param array $variables
* @param DOMElement $refNode
*
* @return Publisher
*/
public function publishBefore(DOMElement $subDoc, array $variables, DOMElement $refNode): Publisher
{
$node = $subDoc->cloneNode(true);
$this->publishValues($node, $variables);
$refNode->parentNode->insertBefore($node, $refNode);
return $this;
}
/**
* @param DOMElement $element
* @param string $parent
* @param DOMElement $variable
*
* @return DOMElement
* @throws Exception
*/
private function getSubDocWithVariable(DOMElement $element, string $parent): DOMElement
{ {
if ($element->tagName == 'text:section') { if ($element->tagName == 'text:section') {
$parentNode = $element; // C'est la section qui est dupliquée return $element; // C'est la section qui est dupliquée
} else { } else {
$i = 10; $i = 10;
$found = false; $found = false;
...@@ -392,18 +484,31 @@ class Publisher ...@@ -392,18 +484,31 @@ class Publisher
if (!$found) { if (!$found) {
throw new \Exception('Le noeud parent de type ' . $parent . ' n\'a pas été trouvé'); throw new \Exception('Le noeud parent de type ' . $parent . ' n\'a pas été trouvé');
} }
return $parentNode;
}
} }
/**
* @param DOMElement $element
* @param string $parent
* @param array $values
*
* @return Publisher
*/
private function publishSubData(DOMElement $element, string $parent, array $values): Publisher
{
$parentNode = $this->getSubDocWithVariable($element, $parent);
foreach ($values as $vals) { foreach ($values as $vals) {
$clone = $parentNode->cloneNode(true); $clone = $parentNode->cloneNode(true);
$this->publishValues($clone, $vals); $this->publishValues($clone, $vals);
$this->insertBefore($clone, $parentNode);
$parentNode->parentNode->insertBefore($clone, $parentNode);
} }
$parentNode->parentNode->removeChild($parentNode); return $this->remove($parentNode);
return $this;
} }
...@@ -413,22 +518,12 @@ class Publisher ...@@ -413,22 +518,12 @@ class Publisher
*/ */
public function publish() public function publish()
{ {
/* On récupère le content du document */
$this->content = new DOMDocument();
$this->content->loadXML($this->getDocument()->getContent()->saveXML());
if ($this->isAutoBreak()) {
$this->addPageBreakStyle();
}
$this->publishBegin(); $this->publishBegin();
$this->body = $this->content->getElementsByTagNameNS($this->getDocument()->getNamespaceUrl('office'), 'text')[0];
$first = true; $first = true;
foreach ($this->values as $values) { foreach ($this->values as $values) {
$bodyNode = $this->body->cloneNode(true); $bodyNode = $this->body->cloneNode(true);
if ($first) { if ($first) {
$this->getDocument()->getStylist()->setVariables($values);
$first = false; $first = false;
} elseif ($this->isAutoBreak()) { } elseif ($this->isAutoBreak()) {
$this->addPageBreak($bodyNode); $this->addPageBreak($bodyNode);
...@@ -440,9 +535,6 @@ class Publisher ...@@ -440,9 +535,6 @@ class Publisher
} }
$this->publishEnd(); $this->publishEnd();
/* On renvoie le content dans le document */
$this->getDocument()->getArchive()->addFromString('content.xml', $this->outContent);
} }
...@@ -511,4 +603,29 @@ class Publisher ...@@ -511,4 +603,29 @@ class Publisher
{ {
return $this->outContent; return $this->outContent;
} }
/**
* @return bool
*/
public function isPublished(): bool
{
return $this->published;
}
/**
* @param bool $published
*
* @return Publisher
*/
public function setPublished(bool $published): Publisher
{
$this->published = $published;
return $this;
}
} }
\ No newline at end of file
...@@ -237,23 +237,27 @@ class Stylist ...@@ -237,23 +237,27 @@ class Stylist
/** /**
* @param DOMElement $element * @param DOMElement $element
* @param string $value * @param mixed $value
* *
* @return Publisher * @return Publisher
*/ */
public function setVariable(DOMElement $element, string $value): Stylist public function setVariable(DOMElement $element, $value): Stylist
{ {
$textNs = $this->getDocument()->getNamespaceUrl('text'); $textNs = $this->getDocument()->getNamespaceUrl('text');
$document = $element->ownerDocument; $document = $element->ownerDocument;
if (is_string($value) && false !== strpos($value, "\n")){
$value = explode("\n", $value); $value = explode("\n", $value);
}else{
$value = (array)$value;
}
for ($i = 0; $i < count($value); $i++) { for ($i = 0; $i < count($value); $i++) {
if ($i > 0) { if ($i > 0) {
$returnVNode = $document->createElementNS($textNs, 'text:line-break'); $returnVNode = $document->createElementNS($textNs, 'text:line-break');
$element->parentNode->insertBefore($returnVNode, $element); $element->parentNode->insertBefore($returnVNode, $element);
} }
$vText = $document->createTextNode($value[$i]); $vText = $document->createTextNode($this->getDocument()->formatValue($element->nodeValue, $value[$i]));
$element->parentNode->insertBefore($vText, $element); $element->parentNode->insertBefore($vText, $element);
} }
$element->parentNode->removeChild($element); $element->parentNode->removeChild($element);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment