Passed
Pull Request — master (#4426)
by
unknown
13:11
created

Alignment   F

Complexity

Total Complexity 69

Size/Duplication

Total Lines 554
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 1 Features 0
Metric Value
wmc 69
eloc 231
dl 0
loc 554
ccs 157
cts 157
cp 1
rs 2.88
c 3
b 1
f 0

23 Methods

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