Skip to content
Snippets Groups Projects
Select Git revision
  • master
  • detached5
  • detached2
  • detached3
  • detached4
  • 6.x
  • detached
  • 6.1.3
  • 6.1.2
  • 6.1.1
  • 6.1.0
  • 6.0.10
  • 6.0.9
  • 6.0.8
  • 6.0.7
  • 6.0.6
  • 6.0.5
  • 6.0.4
  • 6.0.3
  • 6.0.2
  • 6.0.1
  • 6.0.0
  • 4.0
  • 3.0.2
  • 3.0.1
  • 3.0.0
  • 1.7
27 results

Stylist.php

Blame
  • Laurent Lécluse's avatar
    Laurent Lecluse authored
    Possibilités de contrôle étendu des documents
    081f8642
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Stylist.php 9.43 KiB
    <?php
    
    namespace Unicaen\OpenDocument;
    
    use Exception;
    use DOMDocument;
    use DOMElement;
    use DOMNode;
    use DOMNodeList;
    use UnicaenAuth\Service\PrivilegeServiceFactory;
    use ZipArchive;
    
    class Stylist
    {
    
        /**
         * Lecteur de fichier OpenDocument
         *
         * @var Document
         */
        private $document;
    
    
    
        /**
         * @return Document
         */
        public function getDocument(): Document
        {
            return $this->document;
        }
    
    
    
        /**
         * @param Document $document
         *
         * @return Stylist
         */
        public function setDocument(Document $document): Stylist
        {
            $this->document = $document;
    
            return $this;
        }
    
    
    
        public function getAutomaticStyles()
        {
            $res = $this->find('office:automatic-styles');
    
            return $res->item(0);
        }
    
    
    
        /**
         * @param       $name
         * @param       $family
         * @param array $properties
         *
         * @return DOMElement
         */
        public function addAutomaticStyle($name, $family, array $properties = []): DOMElement
        {
            $ns = $this->newElement('style:style', [
                'style:name'   => $name,
                'style:family' => $family,
            ]);
            foreach ($properties as $proName => $proAttrs) {
                $p = $this->newElement($proName, $proAttrs);
                $ns->appendChild($p);
            }
            $this->getAutomaticStyles()->appendChild($ns);
    
            return $ns;
        }
    
    
    
        /**
         * @param       $text
         * @param array $options
         *
         * @return Stylist
         * @throws Exception
         */
        public function addFiligrane($text, array $options = []): Stylist
        {
            $dw = strlen($text) * 2;
            if ($dw > 20) $dw = 20;
    
            $dh = $dw / strlen($text) * 2;
    
            $defaultOptions = [
                'color'     => '#c0c0c0',
                'opacity'   => 0.5,
                'font-name' => 'Liberation Sans',
                'width'     => $dw,
                'height'    => $dh,
            ];
    
            $options = array_merge($defaultOptions, $options);
    
            $this->addAutomaticStyle('UNICAEN_FIL_MP', 'paragraph', [
                'style:text-properties'    => [
                    'style:font-name' => $options['font-name'],
                    'fo:font-size'    => '1pt',
                ],
                'loext:graphic-properties' => [
                    'draw:fill'       => 'solid',
                    'draw:fill-color' => $options['color'],
                    'draw:opacity'    => round($options['opacity'] * 100) . '%',
                ],
            ]);
    
            $this->addAutomaticStyle('UNICAEN_FIL_MGR', 'graphic', [
                'style:graphic-properties' => [
                    'draw:stroke'                     => 'none',
                    'draw:fill'                       => 'solid',
                    'draw:fill-color'                 => $options['color'],
                    'draw:opacity'                    => round($options['opacity'] * 100) . '%',
                    'draw:auto-grow-height'           => 'false',
                    'draw:auto-grow-width'            => 'false',
                    'fo:min-height'                   => $options['width'] . 'cm',
                    'fo:min-width'                    => $options['height'] . 'cm',
                    'style:run-through'               => 'background',
                    'style:wrap'                      => 'run-through',
                    'style:number-wrapped-paragraphs' => 'no-limit',
                    'style:vertical-pos'              => 'middle',
                    'style:vertical-rel'              => 'page-content',
                    'style:horizontal-pos'            => 'center',
                    'style:horizontal-rel'            => 'page-content',
                    'draw:wrap-influence-on-position' => 'once-concurrent',
                    'style:flow-with-text'            => 'false',
                ],
            ]);
    
            $masterPages = $this->find('style:master-page');
            foreach ($masterPages as $masterPage) {
                $fh = $this->findFrom($masterPage, 'style:header');
                if ($fh->length == 1) {
                    $header = $fh->item(0);
                } else {
                    $header = $this->newElement('style:header');
                    $masterPage->appendChild($header);
                }
    
                $p1            = $this->newElement('text:p', [
                        'text:style-name' => 'Header']
                );
                $draw1         = $this->newElement('draw:custom-shape', [
                    'text:anchor-type'     => "char",
                    'draw:z-index'         => "0",
                    'draw:name'            => "PowerPlusWaterMarkObject",
                    'draw:style-name'      => "UNICAEN_FIL_MGR",
                    'draw:text-style-name' => "UNICAEN_FIL_MP",
                    'svg:width'            => $options['width'] . 'cm',
                    'svg:height'           => $options['height'] . 'cm',
                    'draw:transform'       => "rotate (0.785398163397448) translate (-0.134055555555556cm 15.9845416666667cm)",
                ]);
                $p2            = $this->newElement('text:p');
                $p2->nodeValue = $text;
    
                $draw2 = $this->newElement('draw:enhanced-geometry', [
                    'svg:viewBox'        => "0 0 21600 21600",
                    'draw:text-areas'    => "0 0 21600 21600",
                    'draw:text-path'     => "true",
                    'draw:type'          => "fontwork-plain-text",
                    'draw:modifiers'     => "10800",
                    'draw:enhanced-path' => "M ?f3 0 L ?f5 0 N M ?f6 21600 L ?f7 21600 N",
                ]);
    
                $equations = [
                    'f0' => '$0 -10800',
                    'f1' => '?f0 *2',
                    'f2' => 'abs(?f1 )',
                    'f3' => 'if(?f1 ,0,?f2 )',
                    'f4' => '21600-?f2',
                    'f5' => 'if(?f1 ,?f4 ,21600)',
                    'f6' => 'if(?f1 ,?f2 ,0)',
                    'f7' => 'if(?f1 ,21600,?f4 )',
                ];
                foreach ($equations as $eqn => $eqf) {
                    $eqNode = $this->newElement('draw:equation', [
                        'draw:name'    => $eqn,
                        'draw:formula' => $eqf,
                    ]);
                    $draw2->appendChild($eqNode);
                }
    
                $handle = $this->newElement('draw:handle', [
                    'draw:handle-position'        => '$0 21600',
                    'draw:handle-range-x-minimum' => '6629',
                    'draw:handle-range-x-maximum' => '14971',
                ]);
                $draw2->appendChild($handle);
    
                $header
                    ->appendChild($p1)
                    ->appendChild($draw1)
                    ->appendChild($p2);
    
                $draw1->appendChild($draw2);
            }
            $this->getDocument()->setStylesChanged(true);
    
            return $this;
        }
    
    
    
        /**
         * @param DOMElement $element
         *
         * @return Publisher
         * @throws Exception
         */
        public function getVariables(): array
        {
            $textNs = $this->getDocument()->getNamespaceUrl('text');
    
            $variables = [];
            $vElements = $this->find('text:variable-set');
            foreach ($vElements as $vElement) {
                $name = $vElement->getAttributeNs($textNs, 'name');
    
                if (!isset($variables[$name])) $variables[$name] = [];
                $variables[$name][] = $vElement;
            }
    
            return $variables;
        }
    
    
    
        /**
         * @param DOMElement $element
         * @param mixed      $value
         *
         * @return Publisher
         */
        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($this->getDocument()->formatValue($element->nodeValue, $value[$i]));
                $element->parentNode->insertBefore($vText, $element);
            }
            $element->parentNode->removeChild($element);
            $this->getDocument()->setStylesChanged(true);
    
            return $this;
        }
    
    
    
        /**
         * @param array $variables
         *
         * @return Stylist
         * @throws Exception
         */
        public function setVariables(array $variables): Stylist
        {
            $vars = $this->getVariables();
            foreach( $vars as $name => $elements ){
                if (isset($variables[$name])){
                    foreach( $elements as $element ){
                        $this->setVariable($element, $variables[$name]);
                    }
                }
            }
    
            return $this;
        }
    
    
    
        /**
         * @param string $name
         *
         * @return DOMNode[]
         * @throws Exception
         */
        private function find(string $name): DOMNodeList
        {
            $document = $this->getDocument();
    
            return $document->find($document->getStyles(), $name);
        }
    
    
    
        /**
         * @param DOMNode $node
         * @param         $name
         *
         * @return DOMNodeList
         * @throws Exception
         */
        private function findFrom(DOMNode $node, $name): DOMNodeList
        {
            return $this->getDocument()->find($node, $name);
        }
    
    
    
        /**
         * @param string $name
         * @param array  $attrs
         *
         * @return DOMElement
         */
        private function newElement(string $name, array $attrs = []): DOMElement
        {
            $document = $this->getDocument();
    
            return $document->newElement($document->getStyles(), $name, $attrs);
        }
    }