diff --git a/src/Document.php b/src/Document.php index 81b81a10972ec87cadf828fe8bec10817eb0e7d3..782ae868555b21d6e48ee555baf7e48fb25fea40 100644 --- a/src/Document.php +++ b/src/Document.php @@ -78,6 +78,12 @@ class Document */ private $tmpDir; + /** + * @var array + */ + private $formatters = []; + + /** * @var array */ @@ -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 * @@ -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++. * The destructor method will be called as soon as all references to a particular object are removed or diff --git a/src/Publisher.php b/src/Publisher.php index 3a4b3cbfa381be2ab06e2e3de83155d7ce482631..22fd9506f93010fa311f5776e5c1dee30c03548f 100644 --- a/src/Publisher.php +++ b/src/Publisher.php @@ -13,6 +13,9 @@ class Publisher { const PAGE_BREAK_NAME = 'UNICAEN_PAGE_BREAK'; + const PARAGRAPH = 'text:p'; + const TABLE_ROW = 'table:table-row'; + /** * Lecteur de fichier OpenDocument * @@ -51,6 +54,11 @@ class Publisher */ private $outContent; + /** + * @var bool + */ + private $published = false; + /** @@ -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 * @@ -161,10 +179,6 @@ class Publisher - - - - public function getSections(DOMElement $element): array { $textNs = $this->getDocument()->getNamespaceUrl('text'); @@ -194,23 +208,26 @@ class Publisher /** * @param DOMElement $element - * @param string $value + * @param mixed $value * * @return Publisher */ - public function setVariable(DOMElement $element, string $value): Publisher + protected function setVariable(DOMElement $element, $value): Publisher { $textNs = $this->getDocument()->getNamespaceUrl('text'); - $document = $element->ownerDocument; - $value = explode("\n", $value); + if (is_string($value) && false !== strpos($value, "\n")){ + $value = explode("\n", $value); + }else{ + $value = (array)$value; + } 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($value[$i]); + $vText = $document->createTextNode($this->getDocument()->formatValue($element->nodeValue,$value[$i])); $element->parentNode->insertBefore($vText, $element); } $element->parentNode->removeChild($element); @@ -264,8 +281,16 @@ class Publisher * @return Publisher * @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(); $officeDocumentContentPos = strpos($contentText, '<office:document-content'); $length = strpos($contentText, '>', $officeDocumentContentPos) + 1; @@ -291,6 +316,8 @@ class Publisher } } + $this->body = $this->content->getElementsByTagNameNS($this->getDocument()->getNamespaceUrl('office'), 'text')[0]; + return $this; } @@ -299,10 +326,14 @@ class Publisher /** * @return Publisher */ - private function publishEnd(): Publisher + public function publishEnd(): Publisher { $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; } @@ -315,8 +346,12 @@ class Publisher * @return Publisher * @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); $sections = $this->getSections($element); @@ -362,6 +397,10 @@ class Publisher } } + if ($element === $this->body) { + $this->out($this->content->saveXML($element)); + } + return $this; } @@ -370,14 +409,67 @@ class Publisher /** * @param DOMElement $element * @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 */ - 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') { - $parentNode = $element; // C'est la section qui est dupliquée + return $element; // C'est la section qui est dupliquée } else { $i = 10; $found = false; @@ -392,18 +484,31 @@ class Publisher if (!$found) { 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) { $clone = $parentNode->cloneNode(true); $this->publishValues($clone, $vals); - - $parentNode->parentNode->insertBefore($clone, $parentNode); + $this->insertBefore($clone, $parentNode); } - $parentNode->parentNode->removeChild($parentNode); - - return $this; + return $this->remove($parentNode); } @@ -413,24 +518,14 @@ class Publisher */ 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->body = $this->content->getElementsByTagNameNS($this->getDocument()->getNamespaceUrl('office'), 'text')[0]; $first = true; foreach ($this->values as $values) { $bodyNode = $this->body->cloneNode(true); - if ($first){ - $this->getDocument()->getStylist()->setVariables($values); + if ($first) { $first = false; - }elseif($this->isAutoBreak()){ + } elseif ($this->isAutoBreak()) { $this->addPageBreak($bodyNode); } @@ -440,9 +535,6 @@ class Publisher } $this->publishEnd(); - - /* On renvoie le content dans le document */ - $this->getDocument()->getArchive()->addFromString('content.xml', $this->outContent); } @@ -511,4 +603,29 @@ class Publisher { 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 diff --git a/src/Stylist.php b/src/Stylist.php index 23a00e52a11a9fb7750e554a28ed5c3ab13eded3..60af3e102b5a0af1c1c3aace367de827b723eda7 100644 --- a/src/Stylist.php +++ b/src/Stylist.php @@ -237,23 +237,27 @@ class Stylist /** * @param DOMElement $element - * @param string $value + * @param mixed $value * * @return Publisher */ - public function setVariable(DOMElement $element, string $value): Stylist + public function setVariable(DOMElement $element, $value): Stylist { $textNs = $this->getDocument()->getNamespaceUrl('text'); $document = $element->ownerDocument; - $value = explode("\n", $value); + if (is_string($value) && false !== strpos($value, "\n")){ + $value = explode("\n", $value); + }else{ + $value = (array)$value; + } 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($value[$i]); + $vText = $document->createTextNode($this->getDocument()->formatValue($element->nodeValue, $value[$i])); $element->parentNode->insertBefore($vText, $element); } $element->parentNode->removeChild($element);