Alignment   F
last analyzed

Complexity

Total Complexity 67

Size/Duplication

Total Lines 532
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

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

22 Methods

Rating   Name   Duplication   Size   Complexity  
A getSharedComponent() 0 6 1
A getVertical() 0 7 2
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
A getReadOrder() 0 7 2
B setIndent() 0 20 7
A getTextRotation() 0 7 2
A setReadOrder() 0 13 4
A setShrinkToFit() 0 13 3
A exportArray1() 0 13 1
C applyFromArray() 0 33 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
A __construct() 0 9 2
A getHashCode() 0 16 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 10579
    public function __construct(bool $isSupervisor = false, bool $isConditional = false)
146
    {
147
        // Supervisor?
148 10579
        parent::__construct($isSupervisor);
149
150 10579
        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 59
    public function getStyleArray(array $array): array
173
    {
174 59
        return ['alignment' => $array];
175
    }
176
177
    /**
178
     * Apply styles from array.
179
     *
180
     * <code>
181
     * $spreadsheet->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray(
182
     *        [
183
     *            'horizontal'   => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
184
     *            'vertical'     => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
185
     *            'textRotation' => 0,
186
     *            'wrapText'     => TRUE
187
     *        ]
188
     * );
189
     * </code>
190
     *
191
     * @param array $styleArray Array containing style information
192
     *
193
     * @return $this
194
     */
195 130
    public function applyFromArray(array $styleArray): static
196
    {
197 130
        if ($this->isSupervisor) {
198 1
            $this->getActiveSheet()->getStyle($this->getSelectedCells())
199 1
                ->applyFromArray($this->getStyleArray($styleArray));
200
        } else {
201 130
            if (isset($styleArray['horizontal'])) {
202 56
                $this->setHorizontal($styleArray['horizontal']);
203
            }
204 130
            if (isset($styleArray['justifyLastLine'])) {
205 2
                $this->setJustifyLastLine($styleArray['justifyLastLine']);
206
            }
207 130
            if (isset($styleArray['vertical'])) {
208 78
                $this->setVertical($styleArray['vertical']);
209
            }
210 130
            if (isset($styleArray['textRotation'])) {
211 55
                $this->setTextRotation($styleArray['textRotation']);
212
            }
213 130
            if (isset($styleArray['wrapText'])) {
214 80
                $this->setWrapText($styleArray['wrapText']);
215
            }
216 130
            if (isset($styleArray['shrinkToFit'])) {
217 55
                $this->setShrinkToFit($styleArray['shrinkToFit']);
218
            }
219 130
            if (isset($styleArray['indent'])) {
220 43
                $this->setIndent($styleArray['indent']);
221
            }
222 130
            if (isset($styleArray['readOrder'])) {
223 13
                $this->setReadOrder($styleArray['readOrder']);
224
            }
225
        }
226
227 130
        return $this;
228
    }
229
230
    /**
231
     * Get Horizontal.
232
     */
233 785
    public function getHorizontal(): null|string
234
    {
235 785
        if ($this->isSupervisor) {
236 91
            return $this->getSharedComponent()->getHorizontal();
237
        }
238
239 785
        return $this->horizontal;
240
    }
241
242
    /**
243
     * Set Horizontal.
244
     *
245
     * @param string $horizontalAlignment see self::HORIZONTAL_*
246
     *
247
     * @return $this
248
     */
249 480
    public function setHorizontal(string $horizontalAlignment): static
250
    {
251 480
        $horizontalAlignment = strtolower($horizontalAlignment);
252 480
        if ($horizontalAlignment === self::HORIZONTAL_CENTER_CONTINUOUS_LC) {
253 3
            $horizontalAlignment = self::HORIZONTAL_CENTER_CONTINUOUS;
254
        }
255
256 480
        if ($this->isSupervisor) {
257 32
            $styleArray = $this->getStyleArray(['horizontal' => $horizontalAlignment]);
258 32
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
259
        } else {
260 480
            $this->horizontal = $horizontalAlignment;
261
        }
262
263 480
        return $this;
264
    }
265
266
    /**
267
     * Get Justify Last Line.
268
     */
269 77
    public function getJustifyLastLine(): ?bool
270
    {
271 77
        if ($this->isSupervisor) {
272 12
            return $this->getSharedComponent()->getJustifyLastLine();
273
        }
274
275 77
        return $this->justifyLastLine;
276
    }
277
278
    /**
279
     * Set Justify Last Line.
280
     *
281
     * @return $this
282
     */
283 21
    public function setJustifyLastLine(bool $justifyLastLine): static
284
    {
285 21
        if ($this->isSupervisor) {
286 2
            $styleArray = $this->getStyleArray(['justifyLastLine' => $justifyLastLine]);
287 2
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
288
        } else {
289 21
            $this->justifyLastLine = $justifyLastLine;
290
        }
291
292 21
        return $this;
293
    }
294
295
    /**
296
     * Get Vertical.
297
     */
298 753
    public function getVertical(): null|string
299
    {
300 753
        if ($this->isSupervisor) {
301 24
            return $this->getSharedComponent()->getVertical();
302
        }
303
304 753
        return $this->vertical;
305
    }
306
307
    /**
308
     * Set Vertical.
309
     *
310
     * @param string $verticalAlignment see self::VERTICAL_*
311
     *
312
     * @return $this
313
     */
314 488
    public function setVertical(string $verticalAlignment): static
315
    {
316 488
        $verticalAlignment = strtolower($verticalAlignment);
317
318 488
        if ($this->isSupervisor) {
319 28
            $styleArray = $this->getStyleArray(['vertical' => $verticalAlignment]);
320 28
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
321
        } else {
322 488
            $this->vertical = $verticalAlignment;
323
        }
324
325 488
        return $this;
326
    }
327
328
    /**
329
     * Get TextRotation.
330
     */
331 745
    public function getTextRotation(): null|int
332
    {
333 745
        if ($this->isSupervisor) {
334 25
            return $this->getSharedComponent()->getTextRotation();
335
        }
336
337 745
        return $this->textRotation;
338
    }
339
340
    /**
341
     * Set TextRotation.
342
     *
343
     * @return $this
344
     */
345 837
    public function setTextRotation(int $angleInDegrees): static
346
    {
347
        // Excel2007 value 255 => PhpSpreadsheet value -165
348 837
        if ($angleInDegrees == self::TEXTROTATION_STACK_EXCEL) {
349 3
            $angleInDegrees = self::TEXTROTATION_STACK_PHPSPREADSHEET;
350
        }
351
352
        // Set rotation
353 837
        if (($angleInDegrees >= -90 && $angleInDegrees <= 90) || $angleInDegrees == self::TEXTROTATION_STACK_PHPSPREADSHEET) {
354 835
            if ($this->isSupervisor) {
355 8
                $styleArray = $this->getStyleArray(['textRotation' => $angleInDegrees]);
356 8
                $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
357
            } else {
358 835
                $this->textRotation = $angleInDegrees;
359
            }
360
        } else {
361 2
            throw new PhpSpreadsheetException('Text rotation should be a value between -90 and 90.');
362
        }
363
364 835
        return $this;
365
    }
366
367
    /**
368
     * Get Wrap Text.
369
     */
370 213
    public function getWrapText(): bool
371
    {
372 213
        if ($this->isSupervisor) {
373 15
            return $this->getSharedComponent()->getWrapText();
374
        }
375
376 213
        return $this->wrapText;
377
    }
378
379
    /**
380
     * Set Wrap Text.
381
     *
382
     * @return $this
383
     */
384 857
    public function setWrapText(bool $wrapped): static
385
    {
386 857
        if ($wrapped == '') {
387 819
            $wrapped = false;
388
        }
389 857
        if ($this->isSupervisor) {
390 30
            $styleArray = $this->getStyleArray(['wrapText' => $wrapped]);
391 30
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
392
        } else {
393 857
            $this->wrapText = $wrapped;
394
        }
395
396 857
        return $this;
397
    }
398
399
    /**
400
     * Get Shrink to fit.
401
     */
402 170
    public function getShrinkToFit(): bool
403
    {
404 170
        if ($this->isSupervisor) {
405 10
            return $this->getSharedComponent()->getShrinkToFit();
406
        }
407
408 170
        return $this->shrinkToFit;
409
    }
410
411
    /**
412
     * Set Shrink to fit.
413
     *
414
     * @return $this
415
     */
416 831
    public function setShrinkToFit(bool $shrink): static
417
    {
418 831
        if ($shrink == '') {
419 817
            $shrink = false;
420
        }
421 831
        if ($this->isSupervisor) {
422 17
            $styleArray = $this->getStyleArray(['shrinkToFit' => $shrink]);
423 17
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
424
        } else {
425 831
            $this->shrinkToFit = $shrink;
426
        }
427
428 831
        return $this;
429
    }
430
431
    /**
432
     * Get indent.
433
     */
434 252
    public function getIndent(): int
435
    {
436 252
        if ($this->isSupervisor) {
437 76
            return $this->getSharedComponent()->getIndent();
438
        }
439
440 252
        return $this->indent;
441
    }
442
443
    /**
444
     * Set indent.
445
     *
446
     * @return $this
447
     */
448 822
    public function setIndent(int $indent): static
449
    {
450 822
        if ($indent > 0) {
451
            if (
452 9
                $this->getHorizontal() != self::HORIZONTAL_GENERAL
453 9
                && $this->getHorizontal() != self::HORIZONTAL_LEFT
454 9
                && $this->getHorizontal() != self::HORIZONTAL_RIGHT
455 9
                && $this->getHorizontal() != self::HORIZONTAL_DISTRIBUTED
456
            ) {
457 1
                $indent = 0; // indent not supported
458
            }
459
        }
460 822
        if ($this->isSupervisor) {
461 4
            $styleArray = $this->getStyleArray(['indent' => $indent]);
462 4
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
463
        } else {
464 822
            $this->indent = $indent;
465
        }
466
467 822
        return $this;
468
    }
469
470
    /**
471
     * Get read order.
472
     */
473 77
    public function getReadOrder(): int
474
    {
475 77
        if ($this->isSupervisor) {
476 11
            return $this->getSharedComponent()->getReadOrder();
477
        }
478
479 77
        return $this->readOrder;
480
    }
481
482
    /**
483
     * Set read order.
484
     *
485
     * @return $this
486
     */
487 685
    public function setReadOrder(int $readOrder): static
488
    {
489 685
        if ($readOrder < 0 || $readOrder > 2) {
490 1
            $readOrder = 0;
491
        }
492 685
        if ($this->isSupervisor) {
493 1
            $styleArray = $this->getStyleArray(['readOrder' => $readOrder]);
494 1
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
495
        } else {
496 685
            $this->readOrder = $readOrder;
497
        }
498
499 685
        return $this;
500
    }
501
502
    /**
503
     * Get hash code.
504
     *
505
     * @return string Hash code
506
     */
507 1247
    public function getHashCode(): string
508
    {
509 1247
        if ($this->isSupervisor) {
510 1
            return $this->getSharedComponent()->getHashCode();
511
        }
512
513 1247
        return md5(
514 1247
            $this->horizontal
515 1247
            . (($this->justifyLastLine === null) ? 'null' : ($this->justifyLastLine ? 't' : 'f'))
516 1247
            . $this->vertical
517 1247
            . $this->textRotation
518 1247
            . ($this->wrapText ? 't' : 'f')
519 1247
            . ($this->shrinkToFit ? 't' : 'f')
520 1247
            . $this->indent
521 1247
            . $this->readOrder
522 1247
            . __CLASS__
523 1247
        );
524
    }
525
526 16
    protected function exportArray1(): array
527
    {
528 16
        $exportedArray = [];
529 16
        $this->exportArray2($exportedArray, 'horizontal', $this->getHorizontal());
530 16
        $this->exportArray2($exportedArray, 'justifyLastLine', $this->getJustifyLastLine());
531 16
        $this->exportArray2($exportedArray, 'indent', $this->getIndent());
532 16
        $this->exportArray2($exportedArray, 'readOrder', $this->getReadOrder());
533 16
        $this->exportArray2($exportedArray, 'shrinkToFit', $this->getShrinkToFit());
534 16
        $this->exportArray2($exportedArray, 'textRotation', $this->getTextRotation());
535 16
        $this->exportArray2($exportedArray, 'vertical', $this->getVertical());
536 16
        $this->exportArray2($exportedArray, 'wrapText', $this->getWrapText());
537
538 16
        return $exportedArray;
539
    }
540
}
541