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