Completed
Push — develop ( 782b4e...557e80 )
by Adrien
43:38
created

Style::getProtection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Style;
4
5
use PhpOffice\PhpSpreadsheet\Cell\Cell;
6
use PhpOffice\PhpSpreadsheet\IComparable;
7
use PhpOffice\PhpSpreadsheet\Spreadsheet;
8
9
class Style extends Supervisor implements IComparable
10
{
11
    /**
12
     * Font.
13
     *
14
     * @var Font
15
     */
16
    protected $font;
17
18
    /**
19
     * Fill.
20
     *
21
     * @var Fill
22
     */
23
    protected $fill;
24
25
    /**
26
     * Borders.
27
     *
28
     * @var Borders
29
     */
30
    protected $borders;
31
32
    /**
33
     * Alignment.
34
     *
35
     * @var Alignment
36
     */
37
    protected $alignment;
38
39
    /**
40
     * Number Format.
41
     *
42
     * @var NumberFormat
43
     */
44
    protected $numberFormat;
45
46
    /**
47
     * Conditional styles.
48
     *
49
     * @var Conditional[]
50
     */
51
    protected $conditionalStyles;
52
53
    /**
54
     * Protection.
55
     *
56
     * @var Protection
57
     */
58
    protected $protection;
59
60
    /**
61
     * Index of style in collection. Only used for real style.
62
     *
63
     * @var int
64
     */
65
    protected $index;
66
67
    /**
68
     * Use Quote Prefix when displaying in cell editor. Only used for real style.
69
     *
70
     * @var bool
71
     */
72
    protected $quotePrefix = false;
73
74
    /**
75
     * Create a new Style.
76
     *
77
     * @param bool $isSupervisor Flag indicating if this is a supervisor or not
78
     *         Leave this value at default unless you understand exactly what
79
     *    its ramifications are
80
     * @param bool $isConditional Flag indicating if this is a conditional style or not
81
     *       Leave this value at default unless you understand exactly what
82
     *    its ramifications are
83
     */
84 134
    public function __construct($isSupervisor = false, $isConditional = false)
85
    {
86
        // Supervisor?
87 134
        $this->isSupervisor = $isSupervisor;
88
89
        // Initialise values
90 134
        $this->conditionalStyles = [];
91 134
        $this->font = new Font($isSupervisor, $isConditional);
92 134
        $this->fill = new Fill($isSupervisor, $isConditional);
93 134
        $this->borders = new Borders($isSupervisor, $isConditional);
94 134
        $this->alignment = new Alignment($isSupervisor, $isConditional);
95 134
        $this->numberFormat = new NumberFormat($isSupervisor, $isConditional);
96 134
        $this->protection = new Protection($isSupervisor, $isConditional);
97
98
        // bind parent if we are a supervisor
99 134
        if ($isSupervisor) {
100 134
            $this->font->bindParent($this);
101 134
            $this->fill->bindParent($this);
102 134
            $this->borders->bindParent($this);
103 134
            $this->alignment->bindParent($this);
104 134
            $this->numberFormat->bindParent($this);
105 134
            $this->protection->bindParent($this);
106
        }
107 134
    }
108
109
    /**
110
     * Get the shared style component for the currently active cell in currently active sheet.
111
     * Only used for style supervisor.
112
     *
113
     * @return Style
114
     */
115 7
    public function getSharedComponent()
116
    {
117 7
        $activeSheet = $this->getActiveSheet();
118 7
        $selectedCell = $this->getActiveCell(); // e.g. 'A1'
119
120 7
        if ($activeSheet->cellExists($selectedCell)) {
121 7
            $xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex();
122
        } else {
123 1
            $xfIndex = 0;
124
        }
125
126 7
        return $this->parent->getCellXfByIndex($xfIndex);
0 ignored issues
show
Bug introduced by
The method getCellXfByIndex() does not seem to exist on object<PhpOffice\PhpSpreadsheet\Style\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...
127
    }
128
129
    /**
130
     * Get parent. Only used for style supervisor.
131
     *
132
     * @return Spreadsheet
133
     */
134
    public function getParent()
135
    {
136
        return $this->parent;
137
    }
138
139
    /**
140
     * Build style array from subcomponents.
141
     *
142
     * @param array $array
143
     *
144
     * @return array
145
     */
146
    public function getStyleArray($array)
147
    {
148
        return ['quotePrefix' => $array];
149
    }
150
151
    /**
152
     * Apply styles from array.
153
     *
154
     * <code>
155
     * $spreadsheet->getActiveSheet()->getStyle('B2')->applyFromArray(
156
     *         array(
157
     *             'font'    => array(
158
     *                 'name'      => 'Arial',
159
     *                 'bold'      => true,
160
     *                 'italic'    => false,
161
     *                 'underline' => Font::UNDERLINE_DOUBLE,
162
     *                 'strikethrough'    => false,
163
     *                 'color'     => array(
164
     *                     'rgb' => '808080'
165
     *                 )
166
     *             ),
167
     *             'borders' => array(
168
     *                 'bottom'     => array(
169
     *                     'borderStyle' => Border::BORDER_DASHDOT,
170
     *                     'color' => array(
171
     *                         'rgb' => '808080'
172
     *                     )
173
     *                 ),
174
     *                 'top'     => array(
175
     *                     'borderStyle' => Border::BORDER_DASHDOT,
176
     *                     'color' => array(
177
     *                         'rgb' => '808080'
178
     *                     )
179
     *                 )
180
     *             ),
181
     *             'quotePrefix'    => true
182
     *         )
183
     * );
184
     * </code>
185
     *
186
     * @param array $pStyles Array containing style information
187
     * @param bool $pAdvanced advanced mode for setting borders
188
     *
189
     * @throws Exception
190
     *
191
     * @return Style
192
     */
193 47
    public function applyFromArray(array $pStyles, $pAdvanced = true)
194
    {
195 47
        if ($this->isSupervisor) {
196 46
            $pRange = $this->getSelectedCells();
197
198
            // Uppercase coordinate
199 46
            $pRange = strtoupper($pRange);
200
201
            // Is it a cell range or a single cell?
202 46 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...
203 32
                $rangeA = $pRange;
204 32
                $rangeB = $pRange;
205
            } else {
206 31
                list($rangeA, $rangeB) = explode(':', $pRange);
207
            }
208
209
            // Calculate range outer borders
210 46
            $rangeStart = Cell::coordinateFromString($rangeA);
211 46
            $rangeEnd = Cell::coordinateFromString($rangeB);
212
213
            // Translate column into index
214 46
            $rangeStart[0] = Cell::columnIndexFromString($rangeStart[0]) - 1;
215 46
            $rangeEnd[0] = Cell::columnIndexFromString($rangeEnd[0]) - 1;
216
217
            // Make sure we can loop upwards on rows and columns
218 46 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...
219
                $tmp = $rangeStart;
220
                $rangeStart = $rangeEnd;
221
                $rangeEnd = $tmp;
222
            }
223
224
            // ADVANCED MODE:
225 46
            if ($pAdvanced && isset($pStyles['borders'])) {
226
                // 'allBorders' is a shorthand property for 'outline' and 'inside' and
227
                //        it applies to components that have not been set explicitly
228 18 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...
229 1
                    foreach (['outline', 'inside'] as $component) {
230 1
                        if (!isset($pStyles['borders'][$component])) {
231 1
                            $pStyles['borders'][$component] = $pStyles['borders']['allBorders'];
232
                        }
233
                    }
234 1
                    unset($pStyles['borders']['allBorders']); // not needed any more
235
                }
236
                // '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...
237
                //        it applies to components that have not been set explicitly
238 18 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...
239 13
                    foreach (['top', 'right', 'bottom', 'left'] as $component) {
240 13
                        if (!isset($pStyles['borders'][$component])) {
241 13
                            $pStyles['borders'][$component] = $pStyles['borders']['outline'];
242
                        }
243
                    }
244 13
                    unset($pStyles['borders']['outline']); // not needed any more
245
                }
246
                // 'inside' is a shorthand property for 'vertical' and 'horizontal'
247
                //        it applies to components that have not been set explicitly
248 18 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...
249 1
                    foreach (['vertical', 'horizontal'] as $component) {
250 1
                        if (!isset($pStyles['borders'][$component])) {
251 1
                            $pStyles['borders'][$component] = $pStyles['borders']['inside'];
252
                        }
253
                    }
254 1
                    unset($pStyles['borders']['inside']); // not needed any more
255
                }
256
                // 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...
257 18
                $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3);
258 18
                $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3);
259
260
                // loop through up to 3 x 3 = 9 regions
261 18
                for ($x = 1; $x <= $xMax; ++$x) {
262
                    // start column index for region
263 18
                    $colStart = ($x == 3) ?
264 13
                        Cell::stringFromColumnIndex($rangeEnd[0])
265 18
                            : Cell::stringFromColumnIndex($rangeStart[0] + $x - 1);
266
                    // end column index for region
267 18
                    $colEnd = ($x == 1) ?
268 18
                        Cell::stringFromColumnIndex($rangeStart[0])
269 18
                            : Cell::stringFromColumnIndex($rangeEnd[0] - $xMax + $x);
270
271 18
                    for ($y = 1; $y <= $yMax; ++$y) {
272
                        // which edges are touching the region
273 18
                        $edges = [];
274 18
                        if ($x == 1) {
275
                            // are we at left edge
276 18
                            $edges[] = 'left';
277
                        }
278 18
                        if ($x == $xMax) {
279
                            // are we at right edge
280 18
                            $edges[] = 'right';
281
                        }
282 18
                        if ($y == 1) {
283
                            // are we at top edge?
284 18
                            $edges[] = 'top';
285
                        }
286 18
                        if ($y == $yMax) {
287
                            // are we at bottom edge?
288 18
                            $edges[] = 'bottom';
289
                        }
290
291
                        // start row index for region
292 18
                        $rowStart = ($y == 3) ?
293 18
                            $rangeEnd[1] : $rangeStart[1] + $y - 1;
294
295
                        // end row index for region
296 18
                        $rowEnd = ($y == 1) ?
297 18
                            $rangeStart[1] : $rangeEnd[1] - $yMax + $y;
298
299
                        // build range for region
300 18
                        $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd;
301
302
                        // retrieve relevant style array for region
303 18
                        $regionStyles = $pStyles;
304 18
                        unset($regionStyles['borders']['inside']);
305
306
                        // what are the inner edges of the region when looking at the selection
307 18
                        $innerEdges = array_diff(['top', 'right', 'bottom', 'left'], $edges);
308
309
                        // inner edges that are not touching the region should take the 'inside' border properties if they have been set
310 18
                        foreach ($innerEdges as $innerEdge) {
311
                            switch ($innerEdge) {
312 16
                                case 'top':
313 16 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...
314
                                    // should pick up 'horizontal' border property if set
315 16
                                    if (isset($pStyles['borders']['horizontal'])) {
316
                                        $regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal'];
317
                                    } else {
318 16
                                        unset($regionStyles['borders'][$innerEdge]);
319
                                    }
320
321 16
                                    break;
322 16
                                case 'left':
323 16 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...
324
                                    // should pick up 'vertical' border property if set
325 16
                                    if (isset($pStyles['borders']['vertical'])) {
326
                                        $regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical'];
327
                                    } else {
328 16
                                        unset($regionStyles['borders'][$innerEdge]);
329
                                    }
330
331 16
                                    break;
332
                            }
333
                        }
334
335
                        // apply region style to region by calling applyFromArray() in simple mode
336 18
                        $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false);
337
                    }
338
                }
339
340 18
                return $this;
341
            }
342
343
            // SIMPLE MODE:
344
            // Selection type, inspect
345 46
            if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) {
346
                $selectionType = 'COLUMN';
347 46
            } elseif (preg_match('/^A[0-9]+:XFD[0-9]+$/', $pRange)) {
348
                $selectionType = 'ROW';
349
            } else {
350 46
                $selectionType = 'CELL';
351
            }
352
353
            // First loop through columns, rows, or cells to find out which styles are affected by this operation
354
            switch ($selectionType) {
355 46
                case 'COLUMN':
356
                    $oldXfIndexes = [];
357 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...
358
                        $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
359
                    }
360
361
                    break;
362 46
                case 'ROW':
363
                    $oldXfIndexes = [];
364
                    for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
365
                        if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) {
366
                            $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style
367
                        } else {
368
                            $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;
369
                        }
370
                    }
371
372
                    break;
373 46
                case 'CELL':
374 46
                    $oldXfIndexes = [];
375 46
                    for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
376 46 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...
377 46
                            $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;
378
                        }
379
                    }
380
381 46
                    break;
382
            }
383
384
            // clone each of the affected styles, apply the style array, and add the new styles to the workbook
385 46
            $workbook = $this->getActiveSheet()->getParent();
386 46
            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...
387 46
                $style = $workbook->getCellXfByIndex($oldXfIndex);
388 46
                $newStyle = clone $style;
389 46
                $newStyle->applyFromArray($pStyles);
390
391 46
                if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) {
392
                    // there is already such cell Xf in our collection
393 32
                    $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...
394
                } else {
395
                    // we don't have such a cell Xf, need to add
396 46
                    $workbook->addCellXf($newStyle);
397 46
                    $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...
398
                }
399
            }
400
401
            // Loop through columns, rows, or cells again and update the XF index
402
            switch ($selectionType) {
403 46 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...
404
                    for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
405
                        $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);
406
                        $oldXfIndex = $columnDimension->getXfIndex();
407
                        $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
408
                    }
409
410
                    break;
411 46 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...
412
                    for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
413
                        $rowDimension = $this->getActiveSheet()->getRowDimension($row);
414
                        $oldXfIndex = $rowDimension->getXfIndex() === null ?
415
                            0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style
416
                        $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
417
                    }
418
419
                    break;
420 46
                case 'CELL':
421 46
                    for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
422 46
                        for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
423 46
                            $cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row);
424 46
                            $oldXfIndex = $cell->getXfIndex();
425 46
                            $cell->setXfIndex($newXfIndexes[$oldXfIndex]);
426
                        }
427
                    }
428
429 46
                    break;
430
            }
431
        } else {
432
            // not a supervisor, just apply the style array directly on style object
433 47
            if (isset($pStyles['fill'])) {
434 19
                $this->getFill()->applyFromArray($pStyles['fill']);
435
            }
436 47
            if (isset($pStyles['font'])) {
437 24
                $this->getFont()->applyFromArray($pStyles['font']);
438
            }
439 47
            if (isset($pStyles['borders'])) {
440 19
                $this->getBorders()->applyFromArray($pStyles['borders']);
441
            }
442 47
            if (isset($pStyles['alignment'])) {
443 22
                $this->getAlignment()->applyFromArray($pStyles['alignment']);
444
            }
445 47
            if (isset($pStyles['numberFormat'])) {
446 36
                $this->getNumberFormat()->applyFromArray($pStyles['numberFormat']);
447
            }
448 47
            if (isset($pStyles['protection'])) {
449 13
                $this->getProtection()->applyFromArray($pStyles['protection']);
450
            }
451 47
            if (isset($pStyles['quotePrefix'])) {
452 1
                $this->quotePrefix = $pStyles['quotePrefix'];
453
            }
454
        }
455
456 47
        return $this;
457
    }
458
459
    /**
460
     * Get Fill.
461
     *
462
     * @return Fill
463
     */
464 83
    public function getFill()
465
    {
466 83
        return $this->fill;
467
    }
468
469
    /**
470
     * Get Font.
471
     *
472
     * @return Font
473
     */
474 75
    public function getFont()
475
    {
476 75
        return $this->font;
477
    }
478
479
    /**
480
     * Set font.
481
     *
482
     * @param Font $font
483
     *
484
     * @return Style
485
     */
486 17
    public function setFont(Font $font)
487
    {
488 17
        $this->font = $font;
489
490 17
        return $this;
491
    }
492
493
    /**
494
     * Get Borders.
495
     *
496
     * @return Borders
497
     */
498 81
    public function getBorders()
499
    {
500 81
        return $this->borders;
501
    }
502
503
    /**
504
     * Get Alignment.
505
     *
506
     * @return Alignment
507
     */
508 81
    public function getAlignment()
509
    {
510 81
        return $this->alignment;
511
    }
512
513
    /**
514
     * Get Number Format.
515
     *
516
     * @return NumberFormat
517
     */
518 106
    public function getNumberFormat()
519
    {
520 106
        return $this->numberFormat;
521
    }
522
523
    /**
524
     * Get Conditional Styles. Only used on supervisor.
525
     *
526
     * @return Conditional[]
527
     */
528 2
    public function getConditionalStyles()
529
    {
530 2
        return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell());
531
    }
532
533
    /**
534
     * Set Conditional Styles. Only used on supervisor.
535
     *
536
     * @param Conditional[] $pValue Array of conditional styles
537
     *
538
     * @return Style
539
     */
540 2
    public function setConditionalStyles(array $pValue)
541
    {
542 2
        $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $pValue);
543
544 2
        return $this;
545
    }
546
547
    /**
548
     * Get Protection.
549
     *
550
     * @return Protection
551
     */
552 75
    public function getProtection()
553
    {
554 75
        return $this->protection;
555
    }
556
557
    /**
558
     * Get quote prefix.
559
     *
560
     * @return bool
561
     */
562 56
    public function getQuotePrefix()
563
    {
564 56
        if ($this->isSupervisor) {
565
            return $this->getSharedComponent()->getQuotePrefix();
566
        }
567
568 56
        return $this->quotePrefix;
569
    }
570
571
    /**
572
     * Set quote prefix.
573
     *
574
     * @param bool $pValue
575
     */
576 13
    public function setQuotePrefix($pValue)
577
    {
578 13
        if ($pValue == '') {
579 12
            $pValue = false;
580
        }
581 13
        if ($this->isSupervisor) {
582 1
            $styleArray = ['quotePrefix' => $pValue];
583 1
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
584
        } else {
585 12
            $this->quotePrefix = (bool) $pValue;
586
        }
587
588 13
        return $this;
589
    }
590
591
    /**
592
     * Get hash code.
593
     *
594
     * @return string Hash code
595
     */
596 76
    public function getHashCode()
597
    {
598 76
        $hashConditionals = '';
599 76
        foreach ($this->conditionalStyles as $conditional) {
600
            $hashConditionals .= $conditional->getHashCode();
601
        }
602
603 76
        return md5(
604 76
            $this->fill->getHashCode() .
605 76
            $this->font->getHashCode() .
606 76
            $this->borders->getHashCode() .
607 76
            $this->alignment->getHashCode() .
608 76
            $this->numberFormat->getHashCode() .
609 76
            $hashConditionals .
610 76
            $this->protection->getHashCode() .
611 76
            ($this->quotePrefix ? 't' : 'f') .
612 76
            __CLASS__
613
        );
614
    }
615
616
    /**
617
     * Get own index in style collection.
618
     *
619
     * @return int
620
     */
621 49
    public function getIndex()
622
    {
623 49
        return $this->index;
624
    }
625
626
    /**
627
     * Set own index in style collection.
628
     *
629
     * @param int $pValue
630
     */
631 134
    public function setIndex($pValue)
632
    {
633 134
        $this->index = $pValue;
634 134
    }
635
}
636