1<?php
2
3namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
4
5use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
6use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
7use SimpleXMLElement;
8
9class PageSetup extends BaseParserClass
10{
11    private $worksheet;
12
13    private $worksheetXml;
14
15    public function __construct(Worksheet $workSheet, ?SimpleXMLElement $worksheetXml = null)
16    {
17        $this->worksheet = $workSheet;
18        $this->worksheetXml = $worksheetXml;
19    }
20
21    public function load(array $unparsedLoadedData)
22    {
23        if (!$this->worksheetXml) {
24            return $unparsedLoadedData;
25        }
26
27        $this->margins($this->worksheetXml, $this->worksheet);
28        $unparsedLoadedData = $this->pageSetup($this->worksheetXml, $this->worksheet, $unparsedLoadedData);
29        $this->headerFooter($this->worksheetXml, $this->worksheet);
30        $this->pageBreaks($this->worksheetXml, $this->worksheet);
31
32        return $unparsedLoadedData;
33    }
34
35    private function margins(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void
36    {
37        if ($xmlSheet->pageMargins) {
38            $docPageMargins = $worksheet->getPageMargins();
39            $docPageMargins->setLeft((float) ($xmlSheet->pageMargins['left']));
40            $docPageMargins->setRight((float) ($xmlSheet->pageMargins['right']));
41            $docPageMargins->setTop((float) ($xmlSheet->pageMargins['top']));
42            $docPageMargins->setBottom((float) ($xmlSheet->pageMargins['bottom']));
43            $docPageMargins->setHeader((float) ($xmlSheet->pageMargins['header']));
44            $docPageMargins->setFooter((float) ($xmlSheet->pageMargins['footer']));
45        }
46    }
47
48    private function pageSetup(SimpleXMLElement $xmlSheet, Worksheet $worksheet, array $unparsedLoadedData)
49    {
50        if ($xmlSheet->pageSetup) {
51            $docPageSetup = $worksheet->getPageSetup();
52
53            if (isset($xmlSheet->pageSetup['orientation'])) {
54                $docPageSetup->setOrientation((string) $xmlSheet->pageSetup['orientation']);
55            }
56            if (isset($xmlSheet->pageSetup['paperSize'])) {
57                $docPageSetup->setPaperSize((int) ($xmlSheet->pageSetup['paperSize']));
58            }
59            if (isset($xmlSheet->pageSetup['scale'])) {
60                $docPageSetup->setScale((int) ($xmlSheet->pageSetup['scale']), false);
61            }
62            if (isset($xmlSheet->pageSetup['fitToHeight']) && (int) ($xmlSheet->pageSetup['fitToHeight']) >= 0) {
63                $docPageSetup->setFitToHeight((int) ($xmlSheet->pageSetup['fitToHeight']), false);
64            }
65            if (isset($xmlSheet->pageSetup['fitToWidth']) && (int) ($xmlSheet->pageSetup['fitToWidth']) >= 0) {
66                $docPageSetup->setFitToWidth((int) ($xmlSheet->pageSetup['fitToWidth']), false);
67            }
68            if (
69                isset($xmlSheet->pageSetup['firstPageNumber'], $xmlSheet->pageSetup['useFirstPageNumber']) &&
70                self::boolean((string) $xmlSheet->pageSetup['useFirstPageNumber'])
71            ) {
72                $docPageSetup->setFirstPageNumber((int) ($xmlSheet->pageSetup['firstPageNumber']));
73            }
74            if (isset($xmlSheet->pageSetup['pageOrder'])) {
75                $docPageSetup->setPageOrder((string) $xmlSheet->pageSetup['pageOrder']);
76            }
77
78            $relAttributes = $xmlSheet->pageSetup->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');
79            if (isset($relAttributes['id'])) {
80                $unparsedLoadedData['sheets'][$worksheet->getCodeName()]['pageSetupRelId'] = (string) $relAttributes['id'];
81            }
82        }
83
84        return $unparsedLoadedData;
85    }
86
87    private function headerFooter(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void
88    {
89        if ($xmlSheet->headerFooter) {
90            $docHeaderFooter = $worksheet->getHeaderFooter();
91
92            if (
93                isset($xmlSheet->headerFooter['differentOddEven']) &&
94                self::boolean((string) $xmlSheet->headerFooter['differentOddEven'])
95            ) {
96                $docHeaderFooter->setDifferentOddEven(true);
97            } else {
98                $docHeaderFooter->setDifferentOddEven(false);
99            }
100            if (
101                isset($xmlSheet->headerFooter['differentFirst']) &&
102                self::boolean((string) $xmlSheet->headerFooter['differentFirst'])
103            ) {
104                $docHeaderFooter->setDifferentFirst(true);
105            } else {
106                $docHeaderFooter->setDifferentFirst(false);
107            }
108            if (
109                isset($xmlSheet->headerFooter['scaleWithDoc']) &&
110                !self::boolean((string) $xmlSheet->headerFooter['scaleWithDoc'])
111            ) {
112                $docHeaderFooter->setScaleWithDocument(false);
113            } else {
114                $docHeaderFooter->setScaleWithDocument(true);
115            }
116            if (
117                isset($xmlSheet->headerFooter['alignWithMargins']) &&
118                !self::boolean((string) $xmlSheet->headerFooter['alignWithMargins'])
119            ) {
120                $docHeaderFooter->setAlignWithMargins(false);
121            } else {
122                $docHeaderFooter->setAlignWithMargins(true);
123            }
124
125            $docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader);
126            $docHeaderFooter->setOddFooter((string) $xmlSheet->headerFooter->oddFooter);
127            $docHeaderFooter->setEvenHeader((string) $xmlSheet->headerFooter->evenHeader);
128            $docHeaderFooter->setEvenFooter((string) $xmlSheet->headerFooter->evenFooter);
129            $docHeaderFooter->setFirstHeader((string) $xmlSheet->headerFooter->firstHeader);
130            $docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter);
131        }
132    }
133
134    private function pageBreaks(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void
135    {
136        if ($xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk) {
137            $this->rowBreaks($xmlSheet, $worksheet);
138        }
139        if ($xmlSheet->colBreaks && $xmlSheet->colBreaks->brk) {
140            $this->columnBreaks($xmlSheet, $worksheet);
141        }
142    }
143
144    private function rowBreaks(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void
145    {
146        foreach ($xmlSheet->rowBreaks->brk as $brk) {
147            if ($brk['man']) {
148                $worksheet->setBreak("A{$brk['id']}", Worksheet::BREAK_ROW);
149            }
150        }
151    }
152
153    private function columnBreaks(SimpleXMLElement $xmlSheet, Worksheet $worksheet): void
154    {
155        foreach ($xmlSheet->colBreaks->brk as $brk) {
156            if ($brk['man']) {
157                $worksheet->setBreak(
158                    Coordinate::stringFromColumnIndex(((int) $brk['id']) + 1) . '1',
159                    Worksheet::BREAK_COLUMN
160                );
161            }
162        }
163    }
164}
165