Failed Conditions
Pull Request — master (#3693)
by Franck
13:07
created

Style::mapVerticalAlignment()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Ods\Cell;
4
5
use PhpOffice\PhpSpreadsheet\Helper\Dimension;
6
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
7
use PhpOffice\PhpSpreadsheet\Style\Alignment;
8
use PhpOffice\PhpSpreadsheet\Style\Border;
9
use PhpOffice\PhpSpreadsheet\Style\Borders;
10
use PhpOffice\PhpSpreadsheet\Style\Fill;
11
use PhpOffice\PhpSpreadsheet\Style\Font;
12
use PhpOffice\PhpSpreadsheet\Style\Style as CellStyle;
13
use PhpOffice\PhpSpreadsheet\Worksheet\ColumnDimension;
14
use PhpOffice\PhpSpreadsheet\Worksheet\RowDimension;
15
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
16
17
class Style
18
{
19
    public const CELL_STYLE_PREFIX = 'ce';
20
    public const COLUMN_STYLE_PREFIX = 'co';
21
    public const ROW_STYLE_PREFIX = 'ro';
22
    public const TABLE_STYLE_PREFIX = 'ta';
23
24
    private XMLWriter $writer;
25
26 27
    public function __construct(XMLWriter $writer)
27
    {
28 27
        $this->writer = $writer;
29
    }
30
31 27
    private function mapHorizontalAlignment(string $horizontalAlignment): string
32
    {
33 27
        return match ($horizontalAlignment) {
34 27
            Alignment::HORIZONTAL_CENTER, Alignment::HORIZONTAL_CENTER_CONTINUOUS, Alignment::HORIZONTAL_DISTRIBUTED => 'center',
35 27
            Alignment::HORIZONTAL_RIGHT => 'end',
36 27
            Alignment::HORIZONTAL_FILL, Alignment::HORIZONTAL_JUSTIFY => 'justify',
37 27
            default => 'start',
38 27
        };
39
    }
40
41 27
    private function mapVerticalAlignment(string $verticalAlignment): string
42
    {
43 27
        return match ($verticalAlignment) {
44 27
            Alignment::VERTICAL_TOP => 'top',
45 27
            Alignment::VERTICAL_CENTER => 'middle',
46 27
            Alignment::VERTICAL_DISTRIBUTED, Alignment::VERTICAL_JUSTIFY => 'automatic',
47 27
            default => 'bottom',
48 27
        };
49
    }
50
51 27
    private function writeFillStyle(Fill $fill): void
52
    {
53 27
        switch ($fill->getFillType()) {
54
            case Fill::FILL_SOLID:
55 1
                $this->writer->writeAttribute('fo:background-color', sprintf(
56 1
                    '#%s',
57 1
                    strtolower($fill->getStartColor()->getRGB())
58 1
                ));
59
60 1
                break;
61
            case Fill::FILL_GRADIENT_LINEAR:
62
            case Fill::FILL_GRADIENT_PATH:
63
                /// TODO :: To be implemented
64
                break;
65
            case Fill::FILL_NONE:
66
            default:
67
        }
68
    }
69
70 27
    private function writeBordersStyle(Borders $borders): void
71
    {
72 27
        $this->writeBorderStyle('bottom', $borders->getBottom());
73 27
        $this->writeBorderStyle('left', $borders->getLeft());
74 27
        $this->writeBorderStyle('right', $borders->getRight());
75 27
        $this->writeBorderStyle('top', $borders->getTop());
76
    }
77
78 27
    private function writeBorderStyle(string $direction, Border $border): void
79
    {
80 27
        if ($border->getBorderStyle() === Border::BORDER_NONE) {
81 27
            return;
82
        }
83
84 1
        $this->writer->writeAttribute('fo:border-' . $direction, sprintf(
85 1
            '%s %s #%s',
86 1
            $this->mapBorderWidth($border),
87 1
            $this->mapBorderStyle($border),
88 1
            $border->getColor()->getRGB(),
89 1
        ));
90
    }
91
92 1
    private function mapBorderWidth(Border $border): string
93
    {
94 1
        switch ($border->getBorderStyle()) {
95
            case Border::BORDER_THIN:
96
            case Border::BORDER_DASHED:
97
            case Border::BORDER_DASHDOT:
98
            case Border::BORDER_DASHDOTDOT:
99
            case Border::BORDER_DOTTED:
100
            case Border::BORDER_HAIR:
101
                return '0.75pt';
102
            case Border::BORDER_MEDIUM:
103
            case Border::BORDER_MEDIUMDASHED:
104
            case Border::BORDER_MEDIUMDASHDOT:
105
            case Border::BORDER_MEDIUMDASHDOTDOT:
106
            case Border::BORDER_SLANTDASHDOT:
107
                return '1.75pt';
108
            case Border::BORDER_DOUBLE:
109
            case Border::BORDER_THICK:
110 1
                return '2.5pt';
111
        }
112
113
        return '1pt';
114
    }
115
116 1
    private function mapBorderStyle(Border $border): string
117
    {
118 1
        switch ($border->getBorderStyle()) {
119
            case Border::BORDER_DOTTED:
120
            case Border::BORDER_MEDIUMDASHDOTDOT:
121
                return Border::BORDER_DOTTED;
122
123
            case Border::BORDER_DASHED:
124
            case Border::BORDER_DASHDOT:
125
            case Border::BORDER_DASHDOTDOT:
126
            case Border::BORDER_MEDIUMDASHDOT:
127
            case Border::BORDER_MEDIUMDASHED:
128
            case Border::BORDER_SLANTDASHDOT:
129
                return Border::BORDER_DASHED;
130
131
            case Border::BORDER_DOUBLE:
132
                return Border::BORDER_DOUBLE;
133
134
            case Border::BORDER_HAIR:
135
            case Border::BORDER_MEDIUM:
136
            case Border::BORDER_THICK:
137
            case Border::BORDER_THIN:
138 1
                return 'solid';
139
        }
140
141
        return 'solid';
142
    }
143
144 27
    private function writeCellProperties(CellStyle $style): void
145
    {
146
        // Align
147 27
        $hAlign = $style->getAlignment()->getHorizontal();
148 27
        $vAlign = $style->getAlignment()->getVertical();
149 27
        $wrap = $style->getAlignment()->getWrapText();
150
151 27
        $this->writer->startElement('style:table-cell-properties');
152 27
        if (!empty($vAlign) || $wrap) {
153 27
            if (!empty($vAlign)) {
154 27
                $vAlign = $this->mapVerticalAlignment($vAlign);
155 27
                $this->writer->writeAttribute('style:vertical-align', $vAlign);
156
            }
157 27
            if ($wrap) {
158 1
                $this->writer->writeAttribute('fo:wrap-option', 'wrap');
159
            }
160
        }
161 27
        $this->writer->writeAttribute('style:rotation-align', 'none');
162
163
        // Fill
164 27
        $this->writeFillStyle($style->getFill());
165
166
        // Border
167 27
        $this->writeBordersStyle($style->getBorders());
168
169 27
        $this->writer->endElement();
170
171 27
        if (!empty($hAlign)) {
172 27
            $hAlign = $this->mapHorizontalAlignment($hAlign);
173 27
            $this->writer->startElement('style:paragraph-properties');
174 27
            $this->writer->writeAttribute('fo:text-align', $hAlign);
175 27
            $this->writer->endElement();
176
        }
177
    }
178
179 1
    protected function mapUnderlineStyle(Font $font): string
180
    {
181 1
        return match ($font->getUnderline()) {
182 1
            Font::UNDERLINE_DOUBLE, Font::UNDERLINE_DOUBLEACCOUNTING => 'double',
183 1
            Font::UNDERLINE_SINGLE, Font::UNDERLINE_SINGLEACCOUNTING => 'single',
184 1
            default => 'none',
185 1
        };
186
    }
187
188 27
    protected function writeTextProperties(CellStyle $style): void
189
    {
190
        // Font
191 27
        $this->writer->startElement('style:text-properties');
192
193 27
        $font = $style->getFont();
194
195 27
        if ($font->getBold()) {
196 1
            $this->writer->writeAttribute('fo:font-weight', 'bold');
197 1
            $this->writer->writeAttribute('style:font-weight-complex', 'bold');
198 1
            $this->writer->writeAttribute('style:font-weight-asian', 'bold');
199
        }
200
201 27
        if ($font->getItalic()) {
202 1
            $this->writer->writeAttribute('fo:font-style', 'italic');
203
        }
204
205 27
        $this->writer->writeAttribute('fo:color', sprintf('#%s', $font->getColor()->getRGB()));
206
207 27
        if ($family = $font->getName()) {
208 27
            $this->writer->writeAttribute('fo:font-family', $family);
209
        }
210
211 27
        if ($size = $font->getSize()) {
212 27
            $this->writer->writeAttribute('fo:font-size', sprintf('%.1Fpt', $size));
213
        }
214
215 27
        if ($font->getUnderline() && $font->getUnderline() !== Font::UNDERLINE_NONE) {
216 1
            $this->writer->writeAttribute('style:text-underline-style', 'solid');
217 1
            $this->writer->writeAttribute('style:text-underline-width', 'auto');
218 1
            $this->writer->writeAttribute('style:text-underline-color', 'font-color');
219
220 1
            $underline = $this->mapUnderlineStyle($font);
221 1
            $this->writer->writeAttribute('style:text-underline-type', $underline);
222
        }
223
224 27
        $this->writer->endElement(); // Close style:text-properties
225
    }
226
227 5
    protected function writeColumnProperties(ColumnDimension $columnDimension): void
228
    {
229 5
        $this->writer->startElement('style:table-column-properties');
230 5
        $this->writer->writeAttribute(
231 5
            'style:column-width',
232 5
            round($columnDimension->getWidth(Dimension::UOM_CENTIMETERS), 3) . 'cm'
233 5
        );
234 5
        $this->writer->writeAttribute('fo:break-before', 'auto');
235
236
        // End
237 5
        $this->writer->endElement(); // Close style:table-column-properties
238
    }
239
240 5
    public function writeColumnStyles(ColumnDimension $columnDimension, int $sheetId): void
241
    {
242 5
        $this->writer->startElement('style:style');
243 5
        $this->writer->writeAttribute('style:family', 'table-column');
244 5
        $this->writer->writeAttribute(
245 5
            'style:name',
246 5
            sprintf('%s_%d_%d', self::COLUMN_STYLE_PREFIX, $sheetId, $columnDimension->getColumnNumeric())
247 5
        );
248
249 5
        $this->writeColumnProperties($columnDimension);
250
251
        // End
252 5
        $this->writer->endElement(); // Close style:style
253
    }
254
255
    protected function writeRowProperties(RowDimension $rowDimension): void
256
    {
257
        $this->writer->startElement('style:table-row-properties');
258
        $this->writer->writeAttribute(
259
            'style:row-height',
260
            round($rowDimension->getRowHeight(Dimension::UOM_CENTIMETERS), 3) . 'cm'
261
        );
262
        $this->writer->writeAttribute('style:use-optimal-row-height', 'false');
263
        $this->writer->writeAttribute('fo:break-before', 'auto');
264
265
        // End
266
        $this->writer->endElement(); // Close style:table-row-properties
267
    }
268
269
    public function writeRowStyles(RowDimension $rowDimension, int $sheetId): void
270
    {
271
        $this->writer->startElement('style:style');
272
        $this->writer->writeAttribute('style:family', 'table-row');
273
        $this->writer->writeAttribute(
274
            'style:name',
275
            sprintf('%s_%d_%d', self::ROW_STYLE_PREFIX, $sheetId, $rowDimension->getRowIndex())
276
        );
277
278
        $this->writeRowProperties($rowDimension);
279
280
        // End
281
        $this->writer->endElement(); // Close style:style
282
    }
283
284 27
    public function writeTableStyle(Worksheet $worksheet, int $sheetId): void
285
    {
286 27
        $this->writer->startElement('style:style');
287 27
        $this->writer->writeAttribute('style:family', 'table');
288 27
        $this->writer->writeAttribute(
289 27
            'style:name',
290 27
            sprintf('%s%d', self::TABLE_STYLE_PREFIX, $sheetId)
291 27
        );
292
293 27
        $this->writer->startElement('style:table-properties');
294
295 27
        $this->writer->writeAttribute(
296 27
            'table:display',
297 27
            $worksheet->getSheetState() === Worksheet::SHEETSTATE_VISIBLE ? 'true' : 'false'
298 27
        );
299
300 27
        $this->writer->endElement(); // Close style:table-properties
301 27
        $this->writer->endElement(); // Close style:style
302
    }
303
304 27
    public function write(CellStyle $style): void
305
    {
306 27
        $this->writer->startElement('style:style');
307 27
        $this->writer->writeAttribute('style:name', self::CELL_STYLE_PREFIX . $style->getIndex());
308 27
        $this->writer->writeAttribute('style:family', 'table-cell');
309 27
        $this->writer->writeAttribute('style:parent-style-name', 'Default');
310
311
        // Alignment, fill colour, etc
312 27
        $this->writeCellProperties($style);
313
314
        // style:text-properties
315 27
        $this->writeTextProperties($style);
316
317
        // End
318 27
        $this->writer->endElement(); // Close style:style
319
    }
320
}
321