Select Git revision
Stylist.php
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);
}
}