Passed
Push — master ( 8fc7d9...eeb858 )
by Mark
14:21
created

Cell::getStyle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Cell;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
7
use PhpOffice\PhpSpreadsheet\Collection\Cells;
8
use PhpOffice\PhpSpreadsheet\Exception;
9
use PhpOffice\PhpSpreadsheet\RichText\RichText;
10
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDate;
11
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
12
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\CellStyleAssessor;
13
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
14
use PhpOffice\PhpSpreadsheet\Style\Style;
15
use PhpOffice\PhpSpreadsheet\Worksheet\Table;
16
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
17
18
class Cell
19
{
20
    /**
21
     * Value binder to use.
22
     *
23
     * @var IValueBinder
24
     */
25
    private static $valueBinder;
26
27
    /**
28
     * Value of the cell.
29
     *
30
     * @var mixed
31
     */
32
    private $value;
33
34
    /**
35
     *    Calculated value of the cell (used for caching)
36
     *    This returns the value last calculated by MS Excel or whichever spreadsheet program was used to
37
     *        create the original spreadsheet file.
38
     *    Note that this value is not guaranteed to reflect the actual calculated value because it is
39
     *        possible that auto-calculation was disabled in the original spreadsheet, and underlying data
40
     *        values used by the formula have changed since it was last calculated.
41
     *
42
     * @var mixed
43
     */
44
    private $calculatedValue;
45
46
    /**
47
     * Type of the cell data.
48
     *
49
     * @var string
50
     */
51
    private $dataType;
52
53
    /**
54
     * The collection of cells that this cell belongs to (i.e. The Cell Collection for the parent Worksheet).
55
     *
56
     * @var ?Cells
57
     */
58
    private $parent;
59
60
    /**
61
     * Index to the cellXf reference for the styling of this cell.
62
     *
63
     * @var int
64
     */
65
    private $xfIndex = 0;
66
67
    /**
68
     * Attributes of the formula.
69
     *
70
     * @var mixed
71
     */
72
    private $formulaAttributes;
73
74
    /**
75
     * Update the cell into the cell collection.
76
     *
77
     * @return $this
78
     */
79 9746
    public function updateInCollection(): self
80
    {
81 9746
        $parent = $this->parent;
82 9746
        if ($parent === null) {
83 2
            throw new Exception('Cannot update when cell is not bound to a worksheet');
84
        }
85 9744
        $parent->update($this);
86
87 9744
        return $this;
88
    }
89
90 9320
    public function detach(): void
91
    {
92 9320
        $this->parent = null;
93
    }
94
95 8749
    public function attach(Cells $parent): void
96
    {
97 8749
        $this->parent = $parent;
98
    }
99
100
    /**
101
     * Create a new Cell.
102
     *
103
     * @param mixed $value
104
     */
105 9795
    public function __construct($value, ?string $dataType, Worksheet $worksheet)
106
    {
107
        // Initialise cell value
108 9795
        $this->value = $value;
109
110
        // Set worksheet cache
111 9795
        $this->parent = $worksheet->getCellCollection();
112
113
        // Set datatype?
114 9795
        if ($dataType !== null) {
115 9795
            if ($dataType == DataType::TYPE_STRING2) {
116
                $dataType = DataType::TYPE_STRING;
117
            }
118 9795
            $this->dataType = $dataType;
119
        } elseif (self::getValueBinder()->bindValue($this, $value) === false) {
120
            throw new Exception('Value could not be bound to cell.');
121
        }
122
    }
123
124
    /**
125
     * Get cell coordinate column.
126
     *
127
     * @return string
128
     */
129 494
    public function getColumn()
130
    {
131 494
        $parent = $this->parent;
132 494
        if ($parent === null) {
133 1
            throw new Exception('Cannot get column when cell is not bound to a worksheet');
134
        }
135
136 493
        return $parent->getCurrentColumn();
137
    }
138
139
    /**
140
     * Get cell coordinate row.
141
     *
142
     * @return int
143
     */
144 478
    public function getRow()
145
    {
146 478
        $parent = $this->parent;
147 478
        if ($parent === null) {
148 1
            throw new Exception('Cannot get row when cell is not bound to a worksheet');
149
        }
150
151 477
        return $parent->getCurrentRow();
152
    }
153
154
    /**
155
     * Get cell coordinate.
156
     *
157
     * @return string
158
     */
159 9751
    public function getCoordinate()
160
    {
161 9751
        $parent = $this->parent;
162 9751
        if ($parent !== null) {
163 9751
            $coordinate = $parent->getCurrentCoordinate();
164
        } else {
165 2
            $coordinate = null;
166
        }
167 9751
        if ($coordinate === null) {
168 2
            throw new Exception('Coordinate no longer exists');
169
        }
170
171 9751
        return $coordinate;
172
    }
173
174
    /**
175
     * Get cell value.
176
     *
177
     * @return mixed
178
     */
179 9198
    public function getValue()
180
    {
181 9198
        return $this->value;
182
    }
183
184
    /**
185
     * Get cell value with formatting.
186
     */
187 82
    public function getFormattedValue(): string
188
    {
189 82
        return (string) NumberFormat::toFormattedString(
190 82
            $this->getCalculatedValue(),
191 82
            (string) $this->getStyle()->getNumberFormat()->getFormatCode()
192 82
        );
193
    }
194
195
    /**
196
     * @param mixed $oldValue
197
     * @param mixed $newValue
198
     */
199 9718
    protected static function updateIfCellIsTableHeader(Worksheet $workSheet, self $cell, $oldValue, $newValue): void
200
    {
201
//        var_dump('=>', $oldValue, $newValue);
202 9718
        if (StringHelper::strToLower($oldValue ?? '') === StringHelper::strToLower($newValue ?? '')) {
203 726
            return;
204
        }
205
206 9684
        foreach ($workSheet->getTableCollection() as $table) {
207
            /** @var Table $table */
208 8
            if ($cell->isInRange($table->getRange())) {
209 6
                $rangeRowsColumns = Coordinate::getRangeBoundaries($table->getRange());
210 6
                if ($cell->getRow() === (int) $rangeRowsColumns[0][1]) {
211 3
                    Table\Column::updateStructuredReferences($workSheet, $oldValue, $newValue);
212
                }
213
214 6
                return;
215
            }
216
        }
217
    }
218
219
    /**
220
     * Set cell value.
221
     *
222
     *    Sets the value for a cell, automatically determining the datatype using the value binder
223
     *
224
     * @param mixed $value Value
225
     *
226
     * @return $this
227
     */
228 9488
    public function setValue($value): self
229
    {
230 9488
        if (!self::getValueBinder()->bindValue($this, $value)) {
231
            throw new Exception('Value could not be bound to cell.');
232
        }
233
234 9487
        return $this;
235
    }
236
237
    /**
238
     * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder).
239
     *
240
     * @param mixed $value Value
241
     * @param string $dataType Explicit data type, see DataType::TYPE_*
242
     *        Note that PhpSpreadsheet does not validate that the value and datatype are consistent, in using this
243
     *             method, then it is your responsibility as an end-user developer to validate that the value and
244
     *             the datatype match.
245
     *       If you do mismatch value and datatype, then the value you enter may be changed to match the datatype
246
     *          that you specify.
247
     *
248
     * @return Cell
249
     */
250 9721
    public function setValueExplicit($value, string $dataType = DataType::TYPE_STRING)
251
    {
252 9721
        $oldValue = $this->value;
253
254
        // set the value according to data type
255
        switch ($dataType) {
256 255
            case DataType::TYPE_NULL:
257 474
                $this->value = null;
258
259 474
                break;
260 254
            case DataType::TYPE_STRING2:
261 2
                $dataType = DataType::TYPE_STRING;
262
                // no break
263 254
            case DataType::TYPE_STRING:
264
                // Synonym for string
265 230
            case DataType::TYPE_INLINE:
266
                // Rich text
267 5234
                $this->value = DataType::checkString($value);
268
269 5234
                break;
270 229
            case DataType::TYPE_NUMERIC:
271 6594
                if (is_string($value) && !is_numeric($value)) {
272 1
                    throw new Exception('Invalid numeric value for datatype Numeric');
273
                }
274 6593
                $this->value = 0 + $value;
275
276 6593
                break;
277 190
            case DataType::TYPE_FORMULA:
278 8437
                $this->value = (string) $value;
279
280 8437
                break;
281 17
            case DataType::TYPE_BOOL:
282 475
                $this->value = (bool) $value;
283
284 475
                break;
285
            case DataType::TYPE_ISO_DATE:
286 5
                $this->value = SharedDate::convertIsoDate($value);
287 4
                $dataType = DataType::TYPE_NUMERIC;
288
289 4
                break;
290
            case DataType::TYPE_ERROR:
291 19
                $this->value = DataType::checkErrorCode($value);
292
293 19
                break;
294
            default:
295
                throw new Exception('Invalid datatype: ' . $dataType);
296
        }
297
298
        // set the datatype
299 9719
        $this->dataType = $dataType;
300
301 9719
        $this->updateInCollection();
302 9718
        $cellCoordinate = $this->getCoordinate();
303 9718
        self::updateIfCellIsTableHeader($this->getParent()->getParent(), $this, $oldValue, $value); // @phpstan-ignore-line
1 ignored issue
show
Bug introduced by
It seems like $this->getParent()->getParent() can also be of type null; however, parameter $workSheet of PhpOffice\PhpSpreadsheet...teIfCellIsTableHeader() does only seem to accept PhpOffice\PhpSpreadsheet\Worksheet\Worksheet, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

303
        self::updateIfCellIsTableHeader(/** @scrutinizer ignore-type */ $this->getParent()->getParent(), $this, $oldValue, $value); // @phpstan-ignore-line
Loading history...
304
305 9718
        return $this->getParent()->get($cellCoordinate); // @phpstan-ignore-line
306
    }
307
308
    public const CALCULATE_DATE_TIME_ASIS = 0;
309
    public const CALCULATE_DATE_TIME_FLOAT = 1;
310
    public const CALCULATE_TIME_FLOAT = 2;
311
312
    /** @var int */
313
    private static $calculateDateTimeType = self::CALCULATE_DATE_TIME_ASIS;
314
315 45
    public static function getCalculateDateTimeType(): int
316
    {
317 45
        return self::$calculateDateTimeType;
318
    }
319
320 45
    public static function setCalculateDateTimeType(int $calculateDateTimeType): void
321
    {
322
        switch ($calculateDateTimeType) {
323 45
            case self::CALCULATE_DATE_TIME_ASIS:
324 23
            case self::CALCULATE_DATE_TIME_FLOAT:
325 12
            case self::CALCULATE_TIME_FLOAT:
326 45
                self::$calculateDateTimeType = $calculateDateTimeType;
327
328 45
                break;
329
            default:
330 1
                throw new \PhpOffice\PhpSpreadsheet\Calculation\Exception("Invalid value $calculateDateTimeType for calculated date time type");
331
        }
332
    }
333
334
    /**
335
     * Convert date, time, or datetime from int to float if desired.
336
     *
337
     * @param mixed $result
338
     *
339
     * @return mixed
340
     */
341 8750
    private function convertDateTimeInt($result)
342
    {
343 8750
        if (is_int($result)) {
344 4197
            if (self::$calculateDateTimeType === self::CALCULATE_TIME_FLOAT) {
345 4
                if (SharedDate::isDateTime($this, $result, false)) {
346 4
                    $result = (float) $result;
347
                }
348 4193
            } elseif (self::$calculateDateTimeType === self::CALCULATE_DATE_TIME_FLOAT) {
349 4
                if (SharedDate::isDateTime($this, $result, true)) {
350 3
                    $result = (float) $result;
351
                }
352
            }
353
        }
354
355 8750
        return $result;
356
    }
357
358
    /**
359
     * Get calculated cell value.
360
     *
361
     * @param bool $resetLog Whether the calculation engine logger should be reset or not
362
     *
363
     * @return mixed
364
     */
365 8951
    public function getCalculatedValue(bool $resetLog = true)
366
    {
367 8951
        if ($this->dataType === DataType::TYPE_FORMULA) {
368
            try {
369 8149
                $index = $this->getWorksheet()->getParentOrThrow()->getActiveSheetIndex();
370 8149
                $selected = $this->getWorksheet()->getSelectedCells();
371 8149
                $result = Calculation::getInstance(
372 8149
                    $this->getWorksheet()->getParent()
373 8149
                )->calculateCellValue($this, $resetLog);
374 7946
                $result = $this->convertDateTimeInt($result);
375 7946
                $this->getWorksheet()->setSelectedCells($selected);
376 7946
                $this->getWorksheet()->getParentOrThrow()->setActiveSheetIndex($index);
377
                //    We don't yet handle array returns
378 7946
                if (is_array($result)) {
379 7946
                    while (is_array($result)) {
380 3727
                        $result = array_shift($result);
381
                    }
382
                }
383 219
            } catch (Exception $ex) {
384 219
                if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) {
385 1
                    return $this->calculatedValue; // Fallback for calculations referencing external files.
386 219
                } elseif (preg_match('/[Uu]ndefined (name|offset: 2|array key 2)/', $ex->getMessage()) === 1) {
387 28
                    return ExcelError::NAME();
388
                }
389
390 191
                throw new \PhpOffice\PhpSpreadsheet\Calculation\Exception(
391 191
                    $this->getWorksheet()->getTitle() . '!' . $this->getCoordinate() . ' -> ' . $ex->getMessage()
392 191
                );
393
            }
394
395 7946
            if ($result === '#Not Yet Implemented') {
396 2
                return $this->calculatedValue; // Fallback if calculation engine does not support the formula.
397
            }
398
399 7946
            return $result;
400 6254
        } elseif ($this->value instanceof RichText) {
401 18
            return $this->value->getPlainText();
402
        }
403
404 6249
        return $this->convertDateTimeInt($this->value);
405
    }
406
407
    /**
408
     * Set old calculated value (cached).
409
     *
410
     * @param mixed $originalValue Value
411
     */
412 357
    public function setCalculatedValue($originalValue): self
413
    {
414 357
        if ($originalValue !== null) {
415 357
            $this->calculatedValue = (is_numeric($originalValue)) ? (float) $originalValue : $originalValue;
416
        }
417
418 357
        return $this->updateInCollection();
419
    }
420
421
    /**
422
     *    Get old calculated value (cached)
423
     *    This returns the value last calculated by MS Excel or whichever spreadsheet program was used to
424
     *        create the original spreadsheet file.
425
     *    Note that this value is not guaranteed to reflect the actual calculated value because it is
426
     *        possible that auto-calculation was disabled in the original spreadsheet, and underlying data
427
     *        values used by the formula have changed since it was last calculated.
428
     *
429
     * @return mixed
430
     */
431 3
    public function getOldCalculatedValue()
432
    {
433 3
        return $this->calculatedValue;
434
    }
435
436
    /**
437
     * Get cell data type.
438
     */
439 922
    public function getDataType(): string
440
    {
441 922
        return $this->dataType;
442
    }
443
444
    /**
445
     * Set cell data type.
446
     *
447
     * @param string $dataType see DataType::TYPE_*
448
     */
449
    public function setDataType($dataType): self
450
    {
451
        if ($dataType == DataType::TYPE_STRING2) {
452
            $dataType = DataType::TYPE_STRING;
453
        }
454
        $this->dataType = $dataType;
455
456
        return $this->updateInCollection();
457
    }
458
459
    /**
460
     * Identify if the cell contains a formula.
461
     */
462 64
    public function isFormula(): bool
463
    {
464 64
        return $this->dataType === DataType::TYPE_FORMULA && $this->getStyle()->getQuotePrefix() === false;
465
    }
466
467
    /**
468
     *    Does this cell contain Data validation rules?
469
     */
470 13
    public function hasDataValidation(): bool
471
    {
472 13
        if (!isset($this->parent)) {
473 1
            throw new Exception('Cannot check for data validation when cell is not bound to a worksheet');
474
        }
475
476 12
        return $this->getWorksheet()->dataValidationExists($this->getCoordinate());
477
    }
478
479
    /**
480
     * Get Data validation rules.
481
     */
482 23
    public function getDataValidation(): DataValidation
483
    {
484 23
        if (!isset($this->parent)) {
485 1
            throw new Exception('Cannot get data validation for cell that is not bound to a worksheet');
486
        }
487
488 22
        return $this->getWorksheet()->getDataValidation($this->getCoordinate());
489
    }
490
491
    /**
492
     * Set Data validation rules.
493
     */
494 1
    public function setDataValidation(?DataValidation $dataValidation = null): self
495
    {
496 1
        if (!isset($this->parent)) {
497 1
            throw new Exception('Cannot set data validation for cell that is not bound to a worksheet');
498
        }
499
500
        $this->getWorksheet()->setDataValidation($this->getCoordinate(), $dataValidation);
501
502
        return $this->updateInCollection();
503
    }
504
505
    /**
506
     * Does this cell contain valid value?
507
     */
508 4
    public function hasValidValue(): bool
509
    {
510 4
        $validator = new DataValidator();
511
512 4
        return $validator->isValid($this);
513
    }
514
515
    /**
516
     * Does this cell contain a Hyperlink?
517
     */
518 1
    public function hasHyperlink(): bool
519
    {
520 1
        if (!isset($this->parent)) {
521 1
            throw new Exception('Cannot check for hyperlink when cell is not bound to a worksheet');
522
        }
523
524
        return $this->getWorksheet()->hyperlinkExists($this->getCoordinate());
525
    }
526
527
    /**
528
     * Get Hyperlink.
529
     */
530 58
    public function getHyperlink(): Hyperlink
531
    {
532 58
        if (!isset($this->parent)) {
533 1
            throw new Exception('Cannot get hyperlink for cell that is not bound to a worksheet');
534
        }
535
536 57
        return $this->getWorksheet()->getHyperlink($this->getCoordinate());
537
    }
538
539
    /**
540
     * Set Hyperlink.
541
     */
542 1
    public function setHyperlink(?Hyperlink $hyperlink = null): self
543
    {
544 1
        if (!isset($this->parent)) {
545 1
            throw new Exception('Cannot set hyperlink for cell that is not bound to a worksheet');
546
        }
547
548
        $this->getWorksheet()->setHyperlink($this->getCoordinate(), $hyperlink);
549
550
        return $this->updateInCollection();
551
    }
552
553
    /**
554
     * Get cell collection.
555
     *
556
     * @return ?Cells
557
     */
558 9720
    public function getParent()
559
    {
560 9720
        return $this->parent;
561
    }
562
563
    /**
564
     * Get parent worksheet.
565
     */
566 8987
    public function getWorksheet(): Worksheet
567
    {
568 8987
        $parent = $this->parent;
569 8987
        if ($parent !== null) {
570 8987
            $worksheet = $parent->getParent();
571
        } else {
572 1
            $worksheet = null;
573
        }
574
575 8987
        if ($worksheet === null) {
576 1
            throw new Exception('Worksheet no longer exists');
577
        }
578
579 8987
        return $worksheet;
580
    }
581
582 9
    public function getWorksheetOrNull(): ?Worksheet
583
    {
584 9
        $parent = $this->parent;
585 9
        if ($parent !== null) {
586 9
            $worksheet = $parent->getParent();
587
        } else {
588
            $worksheet = null;
589
        }
590
591 9
        return $worksheet;
592
    }
593
594
    /**
595
     * Is this cell in a merge range.
596
     */
597 7
    public function isInMergeRange(): bool
598
    {
599 7
        return (bool) $this->getMergeRange();
600
    }
601
602
    /**
603
     * Is this cell the master (top left cell) in a merge range (that holds the actual data value).
604
     */
605 26
    public function isMergeRangeValueCell(): bool
606
    {
607 26
        if ($mergeRange = $this->getMergeRange()) {
608 5
            $mergeRange = Coordinate::splitRange($mergeRange);
609 5
            [$startCell] = $mergeRange[0];
610
611 5
            return $this->getCoordinate() === $startCell;
612
        }
613
614 23
        return false;
615
    }
616
617
    /**
618
     * If this cell is in a merge range, then return the range.
619
     *
620
     * @return false|string
621
     */
622 29
    public function getMergeRange()
623
    {
624 29
        foreach ($this->getWorksheet()->getMergeCells() as $mergeRange) {
625 5
            if ($this->isInRange($mergeRange)) {
626 5
                return $mergeRange;
627
            }
628
        }
629
630 26
        return false;
631
    }
632
633
    /**
634
     * Get cell style.
635
     */
636 8874
    public function getStyle(): Style
637
    {
638 8874
        return $this->getWorksheet()->getStyle($this->getCoordinate());
639
    }
640
641
    /**
642
     * Get cell style.
643
     */
644 6
    public function getAppliedStyle(): Style
645
    {
646 6
        if ($this->getWorksheet()->conditionalStylesExists($this->getCoordinate()) === false) {
647 2
            return $this->getStyle();
648
        }
649 4
        $range = $this->getWorksheet()->getConditionalRange($this->getCoordinate());
650 4
        if ($range === null) {
651
            return $this->getStyle();
652
        }
653
654 4
        $matcher = new CellStyleAssessor($this, $range);
655
656 4
        return $matcher->matchConditions($this->getWorksheet()->getConditionalStyles($this->getCoordinate()));
657
    }
658
659
    /**
660
     * Re-bind parent.
661
     */
662
    public function rebindParent(Worksheet $parent): self
663
    {
664
        $this->parent = $parent->getCellCollection();
665
666
        return $this->updateInCollection();
667
    }
668
669
    /**
670
     *    Is cell in a specific range?
671
     *
672
     * @param string $range Cell range (e.g. A1:A1)
673
     */
674 227
    public function isInRange(string $range): bool
675
    {
676 227
        [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($range);
677
678
        // Translate properties
679 227
        $myColumn = Coordinate::columnIndexFromString($this->getColumn());
680 227
        $myRow = $this->getRow();
681
682
        // Verify if cell is in range
683 227
        return ($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) &&
684 227
                ($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow);
685
    }
686
687
    /**
688
     * Compare 2 cells.
689
     *
690
     * @param Cell $a Cell a
691
     * @param Cell $b Cell b
692
     *
693
     * @return int Result of comparison (always -1 or 1, never zero!)
694
     */
695
    public static function compareCells(self $a, self $b): int
696
    {
697
        if ($a->getRow() < $b->getRow()) {
698
            return -1;
699
        } elseif ($a->getRow() > $b->getRow()) {
700
            return 1;
701
        } elseif (Coordinate::columnIndexFromString($a->getColumn()) < Coordinate::columnIndexFromString($b->getColumn())) {
702
            return -1;
703
        }
704
705
        return 1;
706
    }
707
708
    /**
709
     * Get value binder to use.
710
     */
711 9489
    public static function getValueBinder(): IValueBinder
712
    {
713 9489
        if (self::$valueBinder === null) {
714 231
            self::$valueBinder = new DefaultValueBinder();
715
        }
716
717 9489
        return self::$valueBinder;
718
    }
719
720
    /**
721
     * Set value binder to use.
722
     */
723 107
    public static function setValueBinder(IValueBinder $binder): void
724
    {
725 107
        self::$valueBinder = $binder;
726
    }
727
728
    /**
729
     * Implement PHP __clone to create a deep clone, not just a shallow copy.
730
     */
731 6
    public function __clone()
732
    {
733 6
        $vars = get_object_vars($this);
734 6
        foreach ($vars as $propertyName => $propertyValue) {
735 6
            if ((is_object($propertyValue)) && ($propertyName !== 'parent')) {
736
                $this->$propertyName = clone $propertyValue;
737
            } else {
738 6
                $this->$propertyName = $propertyValue;
739
            }
740
        }
741
    }
742
743
    /**
744
     * Get index to cellXf.
745
     */
746 9252
    public function getXfIndex(): int
747
    {
748 9252
        return $this->xfIndex;
749
    }
750
751
    /**
752
     * Set index to cellXf.
753
     */
754 1394
    public function setXfIndex(int $indexValue): self
755
    {
756 1394
        $this->xfIndex = $indexValue;
757
758 1394
        return $this->updateInCollection();
759
    }
760
761
    /**
762
     * Set the formula attributes.
763
     *
764
     * @param mixed $attributes
765
     *
766
     * @return $this
767
     */
768
    public function setFormulaAttributes($attributes): self
769
    {
770
        $this->formulaAttributes = $attributes;
771
772
        return $this;
773
    }
774
775
    /**
776
     * Get the formula attributes.
777
     *
778
     * @return mixed
779
     */
780 70
    public function getFormulaAttributes()
781
    {
782 70
        return $this->formulaAttributes;
783
    }
784
785
    /**
786
     * Convert to string.
787
     *
788
     * @return string
789
     */
790
    public function __toString()
791
    {
792
        return (string) $this->getValue();
793
    }
794
}
795