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
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -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
+152 −35
Original line number Diff line number Diff line
@@ -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;

        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,22 +518,12 @@ 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);
                $first = false;
            } 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
+8 −4
Original line number Diff line number Diff line
@@ -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;

        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);