Alignment   F
last analyzed

Complexity

Total Complexity 67

Size/Duplication

Total Lines 538
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 1 Features 0
Metric Value
wmc 67
eloc 218
dl 0
loc 538
ccs 157
cts 157
cp 1
rs 3.04
c 3
b 1
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
A getReadOrder() 0 7 2
A setReadOrder() 0 13 4
A getSharedComponent() 0 6 1
A __construct() 0 9 2
A getVertical() 0 7 2
A getHashCode() 0 16 6
A getHorizontal() 0 7 2
A getWrapText() 0 7 2
A getIndent() 0 7 2
A getJustifyLastLine() 0 7 2
A getShrinkToFit() 0 7 2
B setIndent() 0 20 7
A getTextRotation() 0 7 2
A setShrinkToFit() 0 13 3
A exportArray1() 0 13 1
C applyFromArray() 0 34 10
A setHorizontal() 0 15 3
A setWrapText() 0 13 3
A setVertical() 0 12 2
A setJustifyLastLine() 0 10 2
A getStyleArray() 0 3 1
A setTextRotation() 0 20 6

How to fix   Complexity   

Complex Class

Complex classes like Alignment often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Alignment, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Style;
4
5
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
6
7
class Alignment extends Supervisor
8
{
9
    // Horizontal alignment styles
10
    const HORIZONTAL_GENERAL = 'general';
11
    const HORIZONTAL_LEFT = 'left';
12
    const HORIZONTAL_RIGHT = 'right';
13
    const HORIZONTAL_CENTER = 'center';
14
    const HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous';
15
    const HORIZONTAL_JUSTIFY = 'justify';
16
    const HORIZONTAL_FILL = 'fill';
17
    const HORIZONTAL_DISTRIBUTED = 'distributed'; // Excel2007 only
18
    private const HORIZONTAL_CENTER_CONTINUOUS_LC = 'centercontinuous';
19
    // Mapping for horizontal alignment
20
    const HORIZONTAL_ALIGNMENT_FOR_XLSX = [
21
        self::HORIZONTAL_LEFT => self::HORIZONTAL_LEFT,
22
        self::HORIZONTAL_RIGHT => self::HORIZONTAL_RIGHT,
23
        self::HORIZONTAL_CENTER => self::HORIZONTAL_CENTER,
24
        self::HORIZONTAL_CENTER_CONTINUOUS => self::HORIZONTAL_CENTER_CONTINUOUS,
25
        self::HORIZONTAL_JUSTIFY => self::HORIZONTAL_JUSTIFY,
26
        self::HORIZONTAL_FILL => self::HORIZONTAL_FILL,
27
        self::HORIZONTAL_DISTRIBUTED => self::HORIZONTAL_DISTRIBUTED,
28
    ];
29
    // Mapping for horizontal alignment CSS
30
    const HORIZONTAL_ALIGNMENT_FOR_HTML = [
31
        self::HORIZONTAL_LEFT => self::HORIZONTAL_LEFT,
32
        self::HORIZONTAL_RIGHT => self::HORIZONTAL_RIGHT,
33
        self::HORIZONTAL_CENTER => self::HORIZONTAL_CENTER,
34
        self::HORIZONTAL_CENTER_CONTINUOUS => self::HORIZONTAL_CENTER,
35
        self::HORIZONTAL_JUSTIFY => self::HORIZONTAL_JUSTIFY,
36
        //self::HORIZONTAL_FILL => self::HORIZONTAL_FILL, // no reasonable equivalent for fill
37
        self::HORIZONTAL_DISTRIBUTED => self::HORIZONTAL_JUSTIFY,
38
    ];
39
40
    // Vertical alignment styles
41
    const VERTICAL_BOTTOM = 'bottom';
42
    const VERTICAL_TOP = 'top';
43
    const VERTICAL_CENTER = 'center';
44
    const VERTICAL_JUSTIFY = 'justify';
45
    const VERTICAL_DISTRIBUTED = 'distributed'; // Excel2007 only
46
    // Vertical alignment CSS
47
    private const VERTICAL_BASELINE = 'baseline';
48
    private const VERTICAL_MIDDLE = 'middle';
49
    private const VERTICAL_SUB = 'sub';
50
    private const VERTICAL_SUPER = 'super';
51
    private const VERTICAL_TEXT_BOTTOM = 'text-bottom';
52
    private const VERTICAL_TEXT_TOP = 'text-top';
53
54
    // Mapping for vertical alignment
55
    const VERTICAL_ALIGNMENT_FOR_XLSX = [
56
        self::VERTICAL_BOTTOM => self::VERTICAL_BOTTOM,
57
        self::VERTICAL_TOP => self::VERTICAL_TOP,
58
        self::VERTICAL_CENTER => self::VERTICAL_CENTER,
59
        self::VERTICAL_JUSTIFY => self::VERTICAL_JUSTIFY,
60
        self::VERTICAL_DISTRIBUTED => self::VERTICAL_DISTRIBUTED,
61
        // css settings that arent't in sync with Excel
62
        self::VERTICAL_BASELINE => self::VERTICAL_BOTTOM,
63
        self::VERTICAL_MIDDLE => self::VERTICAL_CENTER,
64
        self::VERTICAL_SUB => self::VERTICAL_BOTTOM,
65
        self::VERTICAL_SUPER => self::VERTICAL_TOP,
66
        self::VERTICAL_TEXT_BOTTOM => self::VERTICAL_BOTTOM,
67
        self::VERTICAL_TEXT_TOP => self::VERTICAL_TOP,
68
    ];
69
70
    // Mapping for vertical alignment for Html
71
    const VERTICAL_ALIGNMENT_FOR_HTML = [
72
        self::VERTICAL_BOTTOM => self::VERTICAL_BOTTOM,
73
        self::VERTICAL_TOP => self::VERTICAL_TOP,
74
        self::VERTICAL_CENTER => self::VERTICAL_MIDDLE,
75
        self::VERTICAL_JUSTIFY => self::VERTICAL_MIDDLE,
76
        self::VERTICAL_DISTRIBUTED => self::VERTICAL_MIDDLE,
77
        // css settings that arent't in sync with Excel
78
        self::VERTICAL_BASELINE => self::VERTICAL_BASELINE,
79
        self::VERTICAL_MIDDLE => self::VERTICAL_MIDDLE,
80
        self::VERTICAL_SUB => self::VERTICAL_SUB,
81
        self::VERTICAL_SUPER => self::VERTICAL_SUPER,
82
        self::VERTICAL_TEXT_BOTTOM => self::VERTICAL_TEXT_BOTTOM,
83
        self::VERTICAL_TEXT_TOP => self::VERTICAL_TEXT_TOP,
84
    ];
85
86
    // Read order
87
    const READORDER_CONTEXT = 0;
88
    const READORDER_LTR = 1;
89
    const READORDER_RTL = 2;
90
91
    // Special value for Text Rotation
92
    const TEXTROTATION_STACK_EXCEL = 255;
93
    const TEXTROTATION_STACK_PHPSPREADSHEET = -165; // 90 - 255
94
95
    /**
96
     * Horizontal alignment.
97
     */
98
    protected ?string $horizontal = self::HORIZONTAL_GENERAL;
99
100
    /**
101
     * Justify Last Line alignment.
102
     */
103
    protected ?bool $justifyLastLine = null;
104
105
    /**
106
     * Vertical alignment.
107
     */
108
    protected ?string $vertical = self::VERTICAL_BOTTOM;
109
110
    /**
111
     * Text rotation.
112
     */
113
    protected ?int $textRotation = 0;
114
115
    /**
116
     * Wrap text.
117
     */
118
    protected bool $wrapText = false;
119
120
    /**
121
     * Shrink to fit.
122
     */
123
    protected bool $shrinkToFit = false;
124
125
    /**
126
     * Indent - only possible with horizontal alignment left and right.
127
     */
128
    protected int $indent = 0;
129
130
    /**
131
     * Read order.
132
     */
133
    protected int $readOrder = 0;
134
135
    /**
136
     * Create a new Alignment.
137
     *
138
     * @param bool $isSupervisor Flag indicating if this is a supervisor or not
139
     *                                       Leave this value at default unless you understand exactly what
140
     *                                          its ramifications are
141
     * @param bool $isConditional Flag indicating if this is a conditional style or not
142
     *                                       Leave this value at default unless you understand exactly what
143
     *                                          its ramifications are
144
     */
145 10638
    public function __construct(bool $isSupervisor = false, bool $isConditional = false)
146
    {
147
        // Supervisor?
148 10638
        parent::__construct($isSupervisor);
149
150 10638
        if ($isConditional) {
151 402
            $this->horizontal = null;
152 402
            $this->vertical = null;
153 402
            $this->textRotation = null;
154
        }
155
    }
156
157
    /**
158
     * Get the shared style component for the currently active cell in currently active sheet.
159
     * Only used for style supervisor.
160
     */
161 103
    public function getSharedComponent(): self
162
    {
163
        /** @var Style $parent */
164 103
        $parent = $this->parent;
165
166 103
        return $parent->getSharedComponent()->getAlignment();
167
    }
168
169
    /**
170
     * Build style array from subcomponents.
171
     *
172
     * @param mixed[] $array
173
     *
174
     * @return array{alignment: mixed[]}
175
     */
176 61
    public function getStyleArray(array $array): array
177
    {
178 61
        return ['alignment' => $array];
179
    }
180
181
    /**
182
     * Apply styles from array.
183
     *
184
     * <code>
185
     * $spreadsheet->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray(
186
     *        [
187
     *            'horizontal'   => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
188
     *            'vertical'     => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
189
     *            'textRotation' => 0,
190
     *            'wrapText'     => TRUE
191
     *        ]
192
     * );
193
     * </code>
194
     *
195
     * @param mixed[] $styleArray Array containing style information
196
     *
197
     * @return $this
198
     */
199 132
    public function applyFromArray(array $styleArray): static
200
    {
201 132
        if ($this->isSupervisor) {
202 1
            $this->getActiveSheet()->getStyle($this->getSelectedCells())
203 1
                ->applyFromArray($this->getStyleArray($styleArray));
204
        } else {
205
            /** @var array{horizontal?: string, vertical?: string, justifyLastLine?: bool, textRotation?: int, wrapText?: bool, shrinkToFit?: bool, readOrder?: int, indent?: int} $styleArray */
206 132
            if (isset($styleArray['horizontal'])) {
207 58
                $this->setHorizontal($styleArray['horizontal']);
208
            }
209 132
            if (isset($styleArray['justifyLastLine'])) {
210 2
                $this->setJustifyLastLine($styleArray['justifyLastLine']);
211
            }
212 132
            if (isset($styleArray['vertical'])) {
213 78
                $this->setVertical($styleArray['vertical']);
214
            }
215 132
            if (isset($styleArray['textRotation'])) {
216 55
                $this->setTextRotation($styleArray['textRotation']);
217
            }
218 132
            if (isset($styleArray['wrapText'])) {
219 80
                $this->setWrapText($styleArray['wrapText']);
220
            }
221 132
            if (isset($styleArray['shrinkToFit'])) {
222 55
                $this->setShrinkToFit($styleArray['shrinkToFit']);
223
            }
224 132
            if (isset($styleArray['indent'])) {
225 43
                $this->setIndent($styleArray['indent']);
226
            }
227 132
            if (isset($styleArray['readOrder'])) {
228 13
                $this->setReadOrder($styleArray['readOrder']);
229
            }
230
        }
231
232 132
        return $this;
233
    }
234
235
    /**
236
     * Get Horizontal.
237
     */
238 793
    public function getHorizontal(): null|string
239
    {
240 793
        if ($this->isSupervisor) {
241 91
            return $this->getSharedComponent()->getHorizontal();
242
        }
243
244 793
        return $this->horizontal;
245
    }
246
247
    /**
248
     * Set Horizontal.
249
     *
250
     * @param string $horizontalAlignment see self::HORIZONTAL_*
251
     *
252
     * @return $this
253
     */
254 490
    public function setHorizontal(string $horizontalAlignment): static
255
    {
256 490
        $horizontalAlignment = strtolower($horizontalAlignment);
257 490
        if ($horizontalAlignment === self::HORIZONTAL_CENTER_CONTINUOUS_LC) {
258 3
            $horizontalAlignment = self::HORIZONTAL_CENTER_CONTINUOUS;
259
        }
260
261 490
        if ($this->isSupervisor) {
262 34
            $styleArray = $this->getStyleArray(['horizontal' => $horizontalAlignment]);
263 34
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
264
        } else {
265 490
            $this->horizontal = $horizontalAlignment;
266
        }
267
268 490
        return $this;
269
    }
270
271
    /**
272
     * Get Justify Last Line.
273
     */
274 77
    public function getJustifyLastLine(): ?bool
275
    {
276 77
        if ($this->isSupervisor) {
277 12
            return $this->getSharedComponent()->getJustifyLastLine();
278
        }
279
280 77
        return $this->justifyLastLine;
281
    }
282
283
    /**
284
     * Set Justify Last Line.
285
     *
286
     * @return $this
287
     */
288 21
    public function setJustifyLastLine(bool $justifyLastLine): static
289
    {
290 21
        if ($this->isSupervisor) {
291 2
            $styleArray = $this->getStyleArray(['justifyLastLine' => $justifyLastLine]);
292 2
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
293
        } else {
294 21
            $this->justifyLastLine = $justifyLastLine;
295
        }
296
297 21
        return $this;
298
    }
299
300
    /**
301
     * Get Vertical.
302
     */
303 761
    public function getVertical(): null|string
304
    {
305 761
        if ($this->isSupervisor) {
306 24
            return $this->getSharedComponent()->getVertical();
307
        }
308
309 761
        return $this->vertical;
310
    }
311
312
    /**
313
     * Set Vertical.
314
     *
315
     * @param string $verticalAlignment see self::VERTICAL_*
316
     *
317
     * @return $this
318
     */
319 494
    public function setVertical(string $verticalAlignment): static
320
    {
321 494
        $verticalAlignment = strtolower($verticalAlignment);
322
323 494
        if ($this->isSupervisor) {
324 28
            $styleArray = $this->getStyleArray(['vertical' => $verticalAlignment]);
325 28
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
326
        } else {
327 494
            $this->vertical = $verticalAlignment;
328
        }
329
330 494
        return $this;
331
    }
332
333
    /**
334
     * Get TextRotation.
335
     */
336 751
    public function getTextRotation(): null|int
337
    {
338 751
        if ($this->isSupervisor) {
339 25
            return $this->getSharedComponent()->getTextRotation();
340
        }
341
342 751
        return $this->textRotation;
343
    }
344
345
    /**
346
     * Set TextRotation.
347
     *
348
     * @return $this
349
     */
350 849
    public function setTextRotation(int $angleInDegrees): static
351
    {
352
        // Excel2007 value 255 => PhpSpreadsheet value -165
353 849
        if ($angleInDegrees == self::TEXTROTATION_STACK_EXCEL) {
354 3
            $angleInDegrees = self::TEXTROTATION_STACK_PHPSPREADSHEET;
355
        }
356
357
        // Set rotation
358 849
        if (($angleInDegrees >= -90 && $angleInDegrees <= 90) || $angleInDegrees == self::TEXTROTATION_STACK_PHPSPREADSHEET) {
359 847
            if ($this->isSupervisor) {
360 8
                $styleArray = $this->getStyleArray(['textRotation' => $angleInDegrees]);
361 8
                $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
362
            } else {
363 847
                $this->textRotation = $angleInDegrees;
364
            }
365
        } else {
366 2
            throw new PhpSpreadsheetException('Text rotation should be a value between -90 and 90.');
367
        }
368
369 847
        return $this;
370
    }
371
372
    /**
373
     * Get Wrap Text.
374
     */
375 220
    public function getWrapText(): bool
376
    {
377 220
        if ($this->isSupervisor) {
378 15
            return $this->getSharedComponent()->getWrapText();
379
        }
380
381 220
        return $this->wrapText;
382
    }
383
384
    /**
385
     * Set Wrap Text.
386
     *
387
     * @return $this
388
     */
389 869
    public function setWrapText(bool $wrapped): static
390
    {
391 869
        if ($wrapped == '') {
392 831
            $wrapped = false;
393
        }
394 869
        if ($this->isSupervisor) {
395 30
            $styleArray = $this->getStyleArray(['wrapText' => $wrapped]);
396 30
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
397
        } else {
398 869
            $this->wrapText = $wrapped;
399
        }
400
401 869
        return $this;
402
    }
403
404
    /**
405
     * Get Shrink to fit.
406
     */
407 175
    public function getShrinkToFit(): bool
408
    {
409 175
        if ($this->isSupervisor) {
410 10
            return $this->getSharedComponent()->getShrinkToFit();
411
        }
412
413 175
        return $this->shrinkToFit;
414
    }
415
416
    /**
417
     * Set Shrink to fit.
418
     *
419
     * @return $this
420
     */
421 843
    public function setShrinkToFit(bool $shrink): static
422
    {
423 843
        if ($shrink == '') {
424 829
            $shrink = false;
425
        }
426 843
        if ($this->isSupervisor) {
427 17
            $styleArray = $this->getStyleArray(['shrinkToFit' => $shrink]);
428 17
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
429
        } else {
430 843
            $this->shrinkToFit = $shrink;
431
        }
432
433 843
        return $this;
434
    }
435
436
    /**
437
     * Get indent.
438
     */
439 259
    public function getIndent(): int
440
    {
441 259
        if ($this->isSupervisor) {
442 76
            return $this->getSharedComponent()->getIndent();
443
        }
444
445 259
        return $this->indent;
446
    }
447
448
    /**
449
     * Set indent.
450
     *
451
     * @return $this
452
     */
453 834
    public function setIndent(int $indent): static
454
    {
455 834
        if ($indent > 0) {
456
            if (
457 9
                $this->getHorizontal() != self::HORIZONTAL_GENERAL
458 9
                && $this->getHorizontal() != self::HORIZONTAL_LEFT
459 9
                && $this->getHorizontal() != self::HORIZONTAL_RIGHT
460 9
                && $this->getHorizontal() != self::HORIZONTAL_DISTRIBUTED
461
            ) {
462 1
                $indent = 0; // indent not supported
463
            }
464
        }
465 834
        if ($this->isSupervisor) {
466 4
            $styleArray = $this->getStyleArray(['indent' => $indent]);
467 4
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
468
        } else {
469 834
            $this->indent = $indent;
470
        }
471
472 834
        return $this;
473
    }
474
475
    /**
476
     * Get read order.
477
     */
478 77
    public function getReadOrder(): int
479
    {
480 77
        if ($this->isSupervisor) {
481 11
            return $this->getSharedComponent()->getReadOrder();
482
        }
483
484 77
        return $this->readOrder;
485
    }
486
487
    /**
488
     * Set read order.
489
     *
490
     * @return $this
491
     */
492 692
    public function setReadOrder(int $readOrder): static
493
    {
494 692
        if ($readOrder < 0 || $readOrder > 2) {
495 1
            $readOrder = 0;
496
        }
497 692
        if ($this->isSupervisor) {
498 1
            $styleArray = $this->getStyleArray(['readOrder' => $readOrder]);
499 1
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
500
        } else {
501 692
            $this->readOrder = $readOrder;
502
        }
503
504 692
        return $this;
505
    }
506
507
    /**
508
     * Get hash code.
509
     *
510
     * @return string Hash code
511
     */
512 1263
    public function getHashCode(): string
513
    {
514 1263
        if ($this->isSupervisor) {
515 1
            return $this->getSharedComponent()->getHashCode();
516
        }
517
518 1263
        return md5(
519 1263
            $this->horizontal
520 1263
            . (($this->justifyLastLine === null) ? 'null' : ($this->justifyLastLine ? 't' : 'f'))
521 1263
            . $this->vertical
522 1263
            . $this->textRotation
523 1263
            . ($this->wrapText ? 't' : 'f')
524 1263
            . ($this->shrinkToFit ? 't' : 'f')
525 1263
            . $this->indent
526 1263
            . $this->readOrder
527 1263
            . __CLASS__
528 1263
        );
529
    }
530
531
    /** @return mixed[] */
532 16
    protected function exportArray1(): array
533
    {
534 16
        $exportedArray = [];
535 16
        $this->exportArray2($exportedArray, 'horizontal', $this->getHorizontal());
536 16
        $this->exportArray2($exportedArray, 'justifyLastLine', $this->getJustifyLastLine());
537 16
        $this->exportArray2($exportedArray, 'indent', $this->getIndent());
538 16
        $this->exportArray2($exportedArray, 'readOrder', $this->getReadOrder());
539 16
        $this->exportArray2($exportedArray, 'shrinkToFit', $this->getShrinkToFit());
540 16
        $this->exportArray2($exportedArray, 'textRotation', $this->getTextRotation());
541 16
        $this->exportArray2($exportedArray, 'vertical', $this->getVertical());
542 16
        $this->exportArray2($exportedArray, 'wrapText', $this->getWrapText());
543
544 16
        return $exportedArray;
545
    }
546
}
547