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