Passed
Pull Request — master (#3339)
by Mark
13:02
created

PageSettings::setVisibilityForWorksheet()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 0
Metric Value
eloc 6
c 0
b 0
f 0
dl 0
loc 10
ccs 6
cts 7
cp 0.8571
rs 10
cc 3
nc 2
nop 2
crap 3.0261
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Reader\Ods;
4
5
use DOMDocument;
6
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
7
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
8
9
class PageSettings
10
{
11
    /**
12
     * @var string
13
     */
14
    private $officeNs;
15
16
    /**
17
     * @var string
18
     */
19
    private $stylesNs;
20
21
    /**
22
     * @var string
23
     */
24
    private $stylesFo;
25
26
    /**
27
     * @var string
28
     */
29
    private $tableNs;
30
31
    /**
32
     * @var string[]
33
     */
34
    private $tableStylesCrossReference = [];
35
36
    /** @var array */
37
    private $pageLayoutStyles = [];
38
39
    /**
40
     * @var string[]
41
     */
42
    private $masterStylesCrossReference = [];
43
44
    /**
45
     * @var string[]
46
     */
47
    private $masterPrintStylesCrossReference = [];
48
49 39
    public function __construct(DOMDocument $styleDom)
50
    {
51 39
        $this->setDomNameSpaces($styleDom);
52 39
        $this->readPageSettingStyles($styleDom);
53 39
        $this->readStyleMasterLookup($styleDom);
54
    }
55
56 39
    private function setDomNameSpaces(DOMDocument $styleDom): void
57
    {
58 39
        $this->officeNs = $styleDom->lookupNamespaceUri('office');
59 39
        $this->stylesNs = $styleDom->lookupNamespaceUri('style');
60 39
        $this->stylesFo = $styleDom->lookupNamespaceUri('fo');
61 39
        $this->tableNs = $styleDom->lookupNamespaceUri('table');
62
    }
63
64 39
    private function readPageSettingStyles(DOMDocument $styleDom): void
65
    {
66 39
        $item0 = $styleDom->getElementsByTagNameNS($this->officeNs, 'automatic-styles')->item(0);
67 39
        $styles = ($item0 === null) ? [] : $item0->getElementsByTagNameNS($this->stylesNs, 'page-layout');
68
69 39
        foreach ($styles as $styleSet) {
70 25
            $styleName = $styleSet->getAttributeNS($this->stylesNs, 'name');
71 25
            $pageLayoutProperties = $styleSet->getElementsByTagNameNS($this->stylesNs, 'page-layout-properties')[0];
72 25
            $styleOrientation = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'print-orientation');
73 25
            $styleScale = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'scale-to');
74 25
            $stylePrintOrder = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'print-page-order');
75 25
            $centered = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'table-centering');
76
77 25
            $marginLeft = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-left');
78 25
            $marginRight = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-right');
79 25
            $marginTop = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-top');
80 25
            $marginBottom = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-bottom');
81 25
            $header = $styleSet->getElementsByTagNameNS($this->stylesNs, 'header-style')[0];
82 25
            $headerProperties = $header->getElementsByTagNameNS($this->stylesNs, 'header-footer-properties')[0];
83 25
            $marginHeader = isset($headerProperties) ? $headerProperties->getAttributeNS($this->stylesFo, 'min-height') : null;
84 25
            $footer = $styleSet->getElementsByTagNameNS($this->stylesNs, 'footer-style')[0];
85 25
            $footerProperties = $footer->getElementsByTagNameNS($this->stylesNs, 'header-footer-properties')[0];
86 25
            $marginFooter = isset($footerProperties) ? $footerProperties->getAttributeNS($this->stylesFo, 'min-height') : null;
87
88 25
            $this->pageLayoutStyles[$styleName] = (object) [
89 25
                'orientation' => $styleOrientation ?: PageSetup::ORIENTATION_DEFAULT,
90 25
                'scale' => $styleScale ?: 100,
91 25
                'printOrder' => $stylePrintOrder,
92 25
                'horizontalCentered' => $centered === 'horizontal' || $centered === 'both',
93 25
                'verticalCentered' => $centered === 'vertical' || $centered === 'both',
94
                // margin size is already stored in inches, so no UOM conversion is required
95 25
                'marginLeft' => (float) ($marginLeft ?? 0.7),
96 25
                'marginRight' => (float) ($marginRight ?? 0.7),
97 25
                'marginTop' => (float) ($marginTop ?? 0.3),
98 25
                'marginBottom' => (float) ($marginBottom ?? 0.3),
99 25
                'marginHeader' => (float) ($marginHeader ?? 0.45),
100 25
                'marginFooter' => (float) ($marginFooter ?? 0.45),
101 25
            ];
102
        }
103
    }
104
105 39
    private function readStyleMasterLookup(DOMDocument $styleDom): void
106
    {
107 39
        $item0 = $styleDom->getElementsByTagNameNS($this->officeNs, 'master-styles')->item(0);
108 39
        $styleMasterLookup = ($item0 === null) ? [] : $item0->getElementsByTagNameNS($this->stylesNs, 'master-page');
109
110 39
        foreach ($styleMasterLookup as $styleMasterSet) {
111 25
            $styleMasterName = $styleMasterSet->getAttributeNS($this->stylesNs, 'name');
112 25
            $pageLayoutName = $styleMasterSet->getAttributeNS($this->stylesNs, 'page-layout-name');
113 25
            $this->masterPrintStylesCrossReference[$styleMasterName] = $pageLayoutName;
114
        }
115
    }
116
117 39
    public function readStyleCrossReferences(DOMDocument $contentDom): void
118
    {
119 39
        $item0 = $contentDom->getElementsByTagNameNS($this->officeNs, 'automatic-styles')->item(0);
120 39
        $styleXReferences = ($item0 === null) ? [] : $item0->getElementsByTagNameNS($this->stylesNs, 'style');
121
122 39
        foreach ($styleXReferences as $styleXreferenceSet) {
123 39
            $styleXRefName = $styleXreferenceSet->getAttributeNS($this->stylesNs, 'name');
124 39
            $stylePageLayoutName = $styleXreferenceSet->getAttributeNS($this->stylesNs, 'master-page-name');
125 39
            $styleFamilyName = $styleXreferenceSet->getAttributeNS($this->stylesNs, 'family');
126 39
            if (!empty($styleFamilyName) && $styleFamilyName === 'table') {
127 39
                $styleVisibility = 'true';
128 39
                foreach ($styleXreferenceSet->getElementsByTagNameNS($this->stylesNs, 'table-properties') as $tableProperties) {
129 39
                    $styleVisibility = $tableProperties->getAttributeNS($this->tableNs, 'display');
130
                }
131 39
                $this->tableStylesCrossReference[$styleXRefName] = $styleVisibility;
132
            }
133 39
            if (!empty($stylePageLayoutName)) {
134 25
                $this->masterStylesCrossReference[$styleXRefName] = $stylePageLayoutName;
135
            }
136
        }
137
    }
138
139 39
    public function setVisibilityForWorksheet(Worksheet $worksheet, string $styleName): void
140
    {
141 39
        if (!array_key_exists($styleName, $this->tableStylesCrossReference)) {
142
            return;
143
        }
144
145 39
        $worksheet->setSheetState(
146 39
            $this->tableStylesCrossReference[$styleName] === 'false'
147 1
                ? Worksheet::SHEETSTATE_HIDDEN
148 39
                : Worksheet::SHEETSTATE_VISIBLE
149 39
        );
150
    }
151
152 39
    public function setPrintSettingsForWorksheet(Worksheet $worksheet, string $styleName): void
153
    {
154 39
        if (!array_key_exists($styleName, $this->masterStylesCrossReference)) {
155 15
            return;
156
        }
157 25
        $masterStyleName = $this->masterStylesCrossReference[$styleName];
158
159 25
        if (!array_key_exists($masterStyleName, $this->masterPrintStylesCrossReference)) {
160
            return;
161
        }
162 25
        $printSettingsIndex = $this->masterPrintStylesCrossReference[$masterStyleName];
163
164 25
        if (!array_key_exists($printSettingsIndex, $this->pageLayoutStyles)) {
165
            return;
166
        }
167 25
        $printSettings = $this->pageLayoutStyles[$printSettingsIndex];
168
169 25
        $worksheet->getPageSetup()
170 25
            ->setOrientation($printSettings->orientation ?? PageSetup::ORIENTATION_DEFAULT)
171 25
            ->setPageOrder($printSettings->printOrder === 'ltr' ? PageSetup::PAGEORDER_OVER_THEN_DOWN : PageSetup::PAGEORDER_DOWN_THEN_OVER)
172 25
            ->setScale((int) trim($printSettings->scale, '%'))
173 25
            ->setHorizontalCentered($printSettings->horizontalCentered)
174 25
            ->setVerticalCentered($printSettings->verticalCentered);
175
176 25
        $worksheet->getPageMargins()
177 25
            ->setLeft($printSettings->marginLeft)
178 25
            ->setRight($printSettings->marginRight)
179 25
            ->setTop($printSettings->marginTop)
180 25
            ->setBottom($printSettings->marginBottom)
181 25
            ->setHeader($printSettings->marginHeader)
182 25
            ->setFooter($printSettings->marginFooter);
183
    }
184
}
185