Completed
Push — develop ( e1f81f...539a89 )
by Adrien
16:11
created

Style   F

Complexity

Total Complexity 87

Size/Duplication

Total Lines 616
Duplicated Lines 11.69 %

Coupling/Cohesion

Components 1
Dependencies 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 72
loc 616
rs 3.9711
c 1
b 0
f 0
wmc 87
lcom 1
cbo 12

19 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 24 2
A getSharedComponent() 0 13 2
A getParent() 0 4 1
A getStyleArray() 0 4 1
F applyFromArray() 72 261 61
A getFill() 0 4 1
A getFont() 0 4 1
A setFont() 0 5 1
A getBorders() 0 4 1
A getAlignment() 0 4 1
A getNumberFormat() 0 4 1
A getConditionalStyles() 0 4 1
A setConditionalStyles() 0 7 2
A getProtection() 0 4 1
A getQuotePrefix() 0 7 2
A setQuotePrefix() 0 13 3
A getHashCode() 0 19 3
A getIndex() 0 4 1
A setIndex() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Style 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Style, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PhpSpreadsheet;
4
5
/**
6
 * Copyright (c) 2006 - 2016 PhpSpreadsheet
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
 *
22
 * @category   PhpSpreadsheet
23
 * @copyright  Copyright (c) 2006 - 2016 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
24
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
25
 * @version    ##VERSION##, ##DATE##
26
 */
27
class Style extends Style\Supervisor implements IComparable
28
{
29
    /**
30
     * Font
31
     *
32
     * @var Style\Font
33
     */
34
    protected $font;
35
36
    /**
37
     * Fill
38
     *
39
     * @var Style\Fill
40
     */
41
    protected $fill;
42
43
    /**
44
     * Borders
45
     *
46
     * @var Style\Borders
47
     */
48
    protected $borders;
49
50
    /**
51
     * Alignment
52
     *
53
     * @var Style\Alignment
54
     */
55
    protected $alignment;
56
57
    /**
58
     * Number Format
59
     *
60
     * @var Style\NumberFormat
61
     */
62
    protected $numberFormat;
63
64
    /**
65
     * Conditional styles
66
     *
67
     * @var Style\Conditional[]
68
     */
69
    protected $conditionalStyles;
70
71
    /**
72
     * Protection
73
     *
74
     * @var Style\Protection
75
     */
76
    protected $protection;
77
78
    /**
79
     * Index of style in collection. Only used for real style.
80
     *
81
     * @var int
82
     */
83
    protected $index;
84
85
    /**
86
     * Use Quote Prefix when displaying in cell editor. Only used for real style.
87
     *
88
     * @var boolean
89
     */
90
    protected $quotePrefix = false;
91
92
    /**
93
     * Create a new Style
94
     *
95
     * @param boolean $isSupervisor Flag indicating if this is a supervisor or not
96
     *         Leave this value at default unless you understand exactly what
97
     *    its ramifications are
98
     * @param boolean $isConditional Flag indicating if this is a conditional style or not
99
     *       Leave this value at default unless you understand exactly what
100
     *    its ramifications are
101
     */
102
    public function __construct($isSupervisor = false, $isConditional = false)
103
    {
104
        // Supervisor?
105
        $this->isSupervisor = $isSupervisor;
106
107
        // Initialise values
108
        $this->conditionalStyles = array();
109
        $this->font         = new Style\Font($isSupervisor, $isConditional);
110
        $this->fill         = new Style\Fill($isSupervisor, $isConditional);
111
        $this->borders      = new Style\Borders($isSupervisor, $isConditional);
112
        $this->alignment    = new Style\Alignment($isSupervisor, $isConditional);
113
        $this->numberFormat = new Style\NumberFormat($isSupervisor, $isConditional);
114
        $this->protection   = new Style\Protection($isSupervisor, $isConditional);
115
116
        // bind parent if we are a supervisor
117
        if ($isSupervisor) {
118
            $this->font->bindParent($this);
119
            $this->fill->bindParent($this);
120
            $this->borders->bindParent($this);
121
            $this->alignment->bindParent($this);
122
            $this->numberFormat->bindParent($this);
123
            $this->protection->bindParent($this);
124
        }
125
    }
126
127
    /**
128
     * Get the shared style component for the currently active cell in currently active sheet.
129
     * Only used for style supervisor
130
     *
131
     * @return Style
132
     */
133
    public function getSharedComponent()
134
    {
135
        $activeSheet = $this->getActiveSheet();
136
        $selectedCell = $this->getActiveCell(); // e.g. 'A1'
137
138
        if ($activeSheet->cellExists($selectedCell)) {
139
            $xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex();
140
        } else {
141
            $xfIndex = 0;
142
        }
143
144
        return $this->parent->getCellXfByIndex($xfIndex);
0 ignored issues
show
Bug introduced by
The method getCellXfByIndex() does not seem to exist on object<PhpSpreadsheet\Style>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
145
    }
146
147
    /**
148
     * Get parent. Only used for style supervisor
149
     *
150
     * @return PhpSpreadsheet
151
     */
152
    public function getParent()
153
    {
154
        return $this->parent;
155
    }
156
157
    /**
158
     * Build style array from subcomponents
159
     *
160
     * @param array $array
161
     * @return array
162
     */
163
    public function getStyleArray($array)
164
    {
165
        return array('quotePrefix' => $array);
166
    }
167
168
    /**
169
     * Apply styles from array
170
     *
171
     * <code>
172
     * $spreadsheet->getActiveSheet()->getStyle('B2')->applyFromArray(
173
     *         array(
174
     *             'font'    => array(
175
     *                 'name'      => 'Arial',
176
     *                 'bold'      => true,
177
     *                 'italic'    => false,
178
     *                 'underline' => \PhpSpreadsheet\Style\Font::UNDERLINE_DOUBLE,
179
     *                 'strike'    => false,
180
     *                 'color'     => array(
181
     *                     'rgb' => '808080'
182
     *                 )
183
     *             ),
184
     *             'borders' => array(
185
     *                 'bottom'     => array(
186
     *                     'style' => \PhpSpreadsheet\Style\Border::BORDER_DASHDOT,
187
     *                     'color' => array(
188
     *                         'rgb' => '808080'
189
     *                     )
190
     *                 ),
191
     *                 'top'     => array(
192
     *                     'style' => \PhpSpreadsheet\Style\Border::BORDER_DASHDOT,
193
     *                     'color' => array(
194
     *                         'rgb' => '808080'
195
     *                     )
196
     *                 )
197
     *             ),
198
     *             'quotePrefix'    => true
199
     *         )
200
     * );
201
     * </code>
202
     *
203
     * @param   array    $pStyles    Array containing style information
204
     * @param   boolean        $pAdvanced    Advanced mode for setting borders.
205
     * @throws  Exception
206
     * @return Style
207
     */
208
    public function applyFromArray($pStyles = null, $pAdvanced = true)
209
    {
210
        if (is_array($pStyles)) {
211
            if ($this->isSupervisor) {
212
                $pRange = $this->getSelectedCells();
213
214
                // Uppercase coordinate
215
                $pRange = strtoupper($pRange);
216
217
                // Is it a cell range or a single cell?
218 View Code Duplication
                if (strpos($pRange, ':') === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
219
                    $rangeA = $pRange;
220
                    $rangeB = $pRange;
221
                } else {
222
                    list($rangeA, $rangeB) = explode(':', $pRange);
223
                }
224
225
                // Calculate range outer borders
226
                $rangeStart = Cell::coordinateFromString($rangeA);
227
                $rangeEnd   = Cell::coordinateFromString($rangeB);
228
229
                // Translate column into index
230
                $rangeStart[0] = Cell::columnIndexFromString($rangeStart[0]) - 1;
231
                $rangeEnd[0]   = Cell::columnIndexFromString($rangeEnd[0]) - 1;
232
233
                // Make sure we can loop upwards on rows and columns
234 View Code Duplication
                if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
235
                    $tmp = $rangeStart;
236
                    $rangeStart = $rangeEnd;
237
                    $rangeEnd = $tmp;
238
                }
239
240
                // ADVANCED MODE:
241
                if ($pAdvanced && isset($pStyles['borders'])) {
242
                    // 'allborders' is a shorthand property for 'outline' and 'inside' and
243
                    //        it applies to components that have not been set explicitly
244 View Code Duplication
                    if (isset($pStyles['borders']['allborders'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
245
                        foreach (array('outline', 'inside') as $component) {
246
                            if (!isset($pStyles['borders'][$component])) {
247
                                $pStyles['borders'][$component] = $pStyles['borders']['allborders'];
248
                            }
249
                        }
250
                        unset($pStyles['borders']['allborders']); // not needed any more
251
                    }
252
                    // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left'
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
253
                    //        it applies to components that have not been set explicitly
254 View Code Duplication
                    if (isset($pStyles['borders']['outline'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
255
                        foreach (array('top', 'right', 'bottom', 'left') as $component) {
256
                            if (!isset($pStyles['borders'][$component])) {
257
                                $pStyles['borders'][$component] = $pStyles['borders']['outline'];
258
                            }
259
                        }
260
                        unset($pStyles['borders']['outline']); // not needed any more
261
                    }
262
                    // 'inside' is a shorthand property for 'vertical' and 'horizontal'
263
                    //        it applies to components that have not been set explicitly
264 View Code Duplication
                    if (isset($pStyles['borders']['inside'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
265
                        foreach (array('vertical', 'horizontal') as $component) {
266
                            if (!isset($pStyles['borders'][$component])) {
267
                                $pStyles['borders'][$component] = $pStyles['borders']['inside'];
268
                            }
269
                        }
270
                        unset($pStyles['borders']['inside']); // not needed any more
271
                    }
272
                    // width and height characteristics of selection, 1, 2, or 3 (for 3 or more)
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
273
                    $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3);
274
                    $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3);
275
276
                    // loop through up to 3 x 3 = 9 regions
277
                    for ($x = 1; $x <= $xMax; ++$x) {
278
                        // start column index for region
279
                        $colStart = ($x == 3) ?
280
                            Cell::stringFromColumnIndex($rangeEnd[0])
281
                                : Cell::stringFromColumnIndex($rangeStart[0] + $x - 1);
282
                        // end column index for region
283
                        $colEnd = ($x == 1) ?
284
                            Cell::stringFromColumnIndex($rangeStart[0])
285
                                : Cell::stringFromColumnIndex($rangeEnd[0] - $xMax + $x);
286
287
                        for ($y = 1; $y <= $yMax; ++$y) {
288
                            // which edges are touching the region
289
                            $edges = array();
290
                            if ($x == 1) {
291
                                // are we at left edge
292
                                $edges[] = 'left';
293
                            }
294
                            if ($x == $xMax) {
295
                                // are we at right edge
296
                                $edges[] = 'right';
297
                            }
298
                            if ($y == 1) {
299
                                // are we at top edge?
300
                                $edges[] = 'top';
301
                            }
302
                            if ($y == $yMax) {
303
                                // are we at bottom edge?
304
                                $edges[] = 'bottom';
305
                            }
306
307
                            // start row index for region
308
                            $rowStart = ($y == 3) ?
309
                                $rangeEnd[1] : $rangeStart[1] + $y - 1;
310
311
                            // end row index for region
312
                            $rowEnd = ($y == 1) ?
313
                                $rangeStart[1] : $rangeEnd[1] - $yMax + $y;
314
315
                            // build range for region
316
                            $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd;
317
318
                            // retrieve relevant style array for region
319
                            $regionStyles = $pStyles;
320
                            unset($regionStyles['borders']['inside']);
321
322
                            // what are the inner edges of the region when looking at the selection
323
                            $innerEdges = array_diff(array('top', 'right', 'bottom', 'left'), $edges);
324
325
                            // inner edges that are not touching the region should take the 'inside' border properties if they have been set
326
                            foreach ($innerEdges as $innerEdge) {
327
                                switch ($innerEdge) {
328
                                    case 'top':
329 View Code Duplication
                                    case 'bottom':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
330
                                        // should pick up 'horizontal' border property if set
331
                                        if (isset($pStyles['borders']['horizontal'])) {
332
                                            $regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal'];
333
                                        } else {
334
                                            unset($regionStyles['borders'][$innerEdge]);
335
                                        }
336
                                        break;
337
                                    case 'left':
338 View Code Duplication
                                    case 'right':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
339
                                        // should pick up 'vertical' border property if set
340
                                        if (isset($pStyles['borders']['vertical'])) {
341
                                            $regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical'];
342
                                        } else {
343
                                            unset($regionStyles['borders'][$innerEdge]);
344
                                        }
345
                                        break;
346
                                }
347
                            }
348
349
                            // apply region style to region by calling applyFromArray() in simple mode
350
                            $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false);
351
                        }
352
                    }
353
                    return $this;
354
                }
355
356
                // SIMPLE MODE:
357
                // Selection type, inspect
358
                if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) {
359
                    $selectionType = 'COLUMN';
360
                } elseif (preg_match('/^A[0-9]+:XFD[0-9]+$/', $pRange)) {
361
                    $selectionType = 'ROW';
362
                } else {
363
                    $selectionType = 'CELL';
364
                }
365
366
                // First loop through columns, rows, or cells to find out which styles are affected by this operation
367
                switch ($selectionType) {
368
                    case 'COLUMN':
369
                        $oldXfIndexes = array();
370 View Code Duplication
                        for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
371
                            $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
372
                        }
373
                        break;
374
                    case 'ROW':
375
                        $oldXfIndexes = array();
376
                        for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
377
                            if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) {
378
                                $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style
379
                            } else {
380
                                $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;
381
                            }
382
                        }
383
                        break;
384
                    case 'CELL':
385
                        $oldXfIndexes = array();
386
                        for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
387 View Code Duplication
                            for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
388
                                $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;
389
                            }
390
                        }
391
                        break;
392
                }
393
394
                // clone each of the affected styles, apply the style array, and add the new styles to the workbook
395
                $workbook = $this->getActiveSheet()->getParent();
396
                foreach ($oldXfIndexes as $oldXfIndex => $dummy) {
0 ignored issues
show
Bug introduced by
The variable $oldXfIndexes does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
397
                    $style = $workbook->getCellXfByIndex($oldXfIndex);
398
                    $newStyle = clone $style;
399
                    $newStyle->applyFromArray($pStyles);
400
401
                    if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) {
402
                        // there is already such cell Xf in our collection
403
                        $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$newXfIndexes was never initialized. Although not strictly required by PHP, it is generally a good practice to add $newXfIndexes = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
404
                    } else {
405
                        // we don't have such a cell Xf, need to add
406
                        $workbook->addCellXf($newStyle);
407
                        $newXfIndexes[$oldXfIndex] = $newStyle->getIndex();
0 ignored issues
show
Bug introduced by
The variable $newXfIndexes does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
408
                    }
409
                }
410
411
                // Loop through columns, rows, or cells again and update the XF index
412
                switch ($selectionType) {
413 View Code Duplication
                    case 'COLUMN':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
414
                        for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
415
                            $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);
416
                            $oldXfIndex = $columnDimension->getXfIndex();
417
                            $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
418
                        }
419
                        break;
420
421 View Code Duplication
                    case 'ROW':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
422
                        for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
423
                            $rowDimension = $this->getActiveSheet()->getRowDimension($row);
424
                            $oldXfIndex = $rowDimension->getXfIndex() === null ?
425
                                0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style
426
                            $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
427
                        }
428
                        break;
429
430
                    case 'CELL':
431
                        for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
432
                            for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
433
                                $cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row);
434
                                $oldXfIndex = $cell->getXfIndex();
435
                                $cell->setXfIndex($newXfIndexes[$oldXfIndex]);
436
                            }
437
                        }
438
                        break;
439
                }
440
            } else {
441
                // not a supervisor, just apply the style array directly on style object
442
                if (array_key_exists('fill', $pStyles)) {
443
                    $this->getFill()->applyFromArray($pStyles['fill']);
444
                }
445
                if (array_key_exists('font', $pStyles)) {
446
                    $this->getFont()->applyFromArray($pStyles['font']);
447
                }
448
                if (array_key_exists('borders', $pStyles)) {
449
                    $this->getBorders()->applyFromArray($pStyles['borders']);
450
                }
451
                if (array_key_exists('alignment', $pStyles)) {
452
                    $this->getAlignment()->applyFromArray($pStyles['alignment']);
453
                }
454
                if (array_key_exists('numberformat', $pStyles)) {
455
                    $this->getNumberFormat()->applyFromArray($pStyles['numberformat']);
456
                }
457
                if (array_key_exists('protection', $pStyles)) {
458
                    $this->getProtection()->applyFromArray($pStyles['protection']);
459
                }
460
                if (array_key_exists('quotePrefix', $pStyles)) {
461
                    $this->quotePrefix = $pStyles['quotePrefix'];
462
                }
463
            }
464
        } else {
465
            throw new Exception("Invalid style array passed.");
466
        }
467
        return $this;
468
    }
469
470
    /**
471
     * Get Fill
472
     *
473
     * @return Style\Fill
474
     */
475
    public function getFill()
476
    {
477
        return $this->fill;
478
    }
479
480
    /**
481
     * Get Font
482
     *
483
     * @return Style\Font
484
     */
485
    public function getFont()
486
    {
487
        return $this->font;
488
    }
489
490
    /**
491
     * Set font
492
     *
493
     * @param Style\Font $font
494
     * @return Style
495
     */
496
    public function setFont(Style\Font $font)
497
    {
498
        $this->font = $font;
499
        return $this;
500
    }
501
502
    /**
503
     * Get Borders
504
     *
505
     * @return Style\Borders
506
     */
507
    public function getBorders()
508
    {
509
        return $this->borders;
510
    }
511
512
    /**
513
     * Get Alignment
514
     *
515
     * @return Style\Alignment
516
     */
517
    public function getAlignment()
518
    {
519
        return $this->alignment;
520
    }
521
522
    /**
523
     * Get Number Format
524
     *
525
     * @return Style\NumberFormat
526
     */
527
    public function getNumberFormat()
528
    {
529
        return $this->numberFormat;
530
    }
531
532
    /**
533
     * Get Conditional Styles. Only used on supervisor.
534
     *
535
     * @return Style\Conditional[]
536
     */
537
    public function getConditionalStyles()
538
    {
539
        return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell());
540
    }
541
542
    /**
543
     * Set Conditional Styles. Only used on supervisor.
544
     *
545
     * @param Style\Conditional[] $pValue Array of condtional styles
546
     * @return Style
547
     */
548
    public function setConditionalStyles($pValue = null)
549
    {
550
        if (is_array($pValue)) {
551
            $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $pValue);
552
        }
553
        return $this;
554
    }
555
556
    /**
557
     * Get Protection
558
     *
559
     * @return Style\Protection
560
     */
561
    public function getProtection()
562
    {
563
        return $this->protection;
564
    }
565
566
    /**
567
     * Get quote prefix
568
     *
569
     * @return boolean
570
     */
571
    public function getQuotePrefix()
572
    {
573
        if ($this->isSupervisor) {
574
            return $this->getSharedComponent()->getQuotePrefix();
575
        }
576
        return $this->quotePrefix;
577
    }
578
579
    /**
580
     * Set quote prefix
581
     *
582
     * @param boolean $pValue
583
     */
584
    public function setQuotePrefix($pValue)
585
    {
586
        if ($pValue == '') {
587
            $pValue = false;
588
        }
589
        if ($this->isSupervisor) {
590
            $styleArray = array('quotePrefix' => $pValue);
591
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
592
        } else {
593
            $this->quotePrefix = (boolean) $pValue;
594
        }
595
        return $this;
596
    }
597
598
    /**
599
     * Get hash code
600
     *
601
     * @return string Hash code
602
     */
603
    public function getHashCode()
604
    {
605
        $hashConditionals = '';
606
        foreach ($this->conditionalStyles as $conditional) {
607
            $hashConditionals .= $conditional->getHashCode();
608
        }
609
610
        return md5(
611
            $this->fill->getHashCode() .
612
            $this->font->getHashCode() .
613
            $this->borders->getHashCode() .
614
            $this->alignment->getHashCode() .
615
            $this->numberFormat->getHashCode() .
616
            $hashConditionals .
617
            $this->protection->getHashCode() .
618
            ($this->quotePrefix  ? 't' : 'f') .
619
            __CLASS__
620
        );
621
    }
622
623
    /**
624
     * Get own index in style collection
625
     *
626
     * @return int
627
     */
628
    public function getIndex()
629
    {
630
        return $this->index;
631
    }
632
633
    /**
634
     * Set own index in style collection
635
     *
636
     * @param int $pValue
637
     */
638
    public function setIndex($pValue)
639
    {
640
        $this->index = $pValue;
641
    }
642
}
643