Passed
Pull Request — master (#3236)
by Mark
11:30
created

Cell::updateIfCellIsTableHeader()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 5.3906

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 15
rs 9.6111
ccs 3
cts 4
cp 0.75
cc 5
nc 5
nop 4
crap 5.3906
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 9550
     * @return $this
78
     */
79 9550
    public function updateInCollection(): self
80 9550
    {
81 2
        $parent = $this->parent;
82
        if ($parent === null) {
83 9548
            throw new Exception('Cannot update when cell is not bound to a worksheet');
84
        }
85 9548
        $parent->update($this);
86
87
        return $this;
88 9124
    }
89
90 9124
    public function detach(): void
91
    {
92
        $this->parent = null;
93 8564
    }
94
95 8564
    public function attach(Cells $parent): void
96
    {
97
        $this->parent = $parent;
98
    }
99
100
    /**
101
     * Create a new Cell.
102
     *
103 9599
     * @param mixed $value
104
     */
105
    public function __construct($value, ?string $dataType, Worksheet $worksheet)
106 9599
    {
107
        // Initialise cell value
108
        $this->value = $value;
109 9599
110
        // Set worksheet cache
111
        $this->parent = $worksheet->getCellCollection();
112 9599
113 9599
        // Set datatype?
114
        if ($dataType !== null) {
115
            if ($dataType == DataType::TYPE_STRING2) {
116 9599
                $dataType = DataType::TYPE_STRING;
117
            }
118
            $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 484
     * @return string
128
     */
129 484
    public function getColumn()
130 484
    {
131 1
        $parent = $this->parent;
132
        if ($parent === null) {
133
            throw new Exception('Cannot get column when cell is not bound to a worksheet');
134 483
        }
135
136
        return $parent->getCurrentColumn();
137
    }
138
139
    /**
140
     * Get cell coordinate row.
141
     *
142 456
     * @return int
143
     */
144 456
    public function getRow()
145 456
    {
146 1
        $parent = $this->parent;
147
        if ($parent === null) {
148
            throw new Exception('Cannot get row when cell is not bound to a worksheet');
149 455
        }
150
151
        return $parent->getCurrentRow();
152
    }
153
154
    /**
155
     * Get cell coordinate.
156
     *
157 9555
     * @return string
158
     */
159 9555
    public function getCoordinate()
160 9555
    {
161 9555
        $parent = $this->parent;
162
        if ($parent !== null) {
163 2
            $coordinate = $parent->getCurrentCoordinate();
164
        } else {
165 9555
            $coordinate = null;
166 2
        }
167
        if ($coordinate === null) {
168
            throw new Exception('Coordinate no longer exists');
169 9555
        }
170
171
        return $coordinate;
172
    }
173
174
    /**
175
     * Get cell value.
176
     *
177 9030
     * @return mixed
178
     */
179 9030
    public function getValue()
180
    {
181
        return $this->value;
182
    }
183
184
    /**
185 82
     * Get cell value with formatting.
186
     */
187 82
    public function getFormattedValue(): string
188 82
    {
189 82
        return (string) NumberFormat::toFormattedString(
190
            $this->getCalculatedValue(),
191
            (string) $this->getStyle()->getNumberFormat()->getFormatCode()
192
        );
193
    }
194
195
    /**
196
     * @param mixed $oldValue
197
     * @param mixed $newValue
198
     */
199
    protected static function updateIfCellIsTableHeader(Worksheet $workSheet, self $cell, $oldValue, $newValue): void
200
    {
201
        if (StringHelper::strToLower($oldValue ?? '') === StringHelper::strToLower($newValue ?? '')) {
202 9294
            return;
203
        }
204 9294
205
        foreach ($workSheet->getTableCollection() as $table) {
206
            /** @var Table $table */
207
            if ($cell->isInRange($table->getRange())) {
208 9293
                $rangeRowsColumns = Coordinate::getRangeBoundaries($table->getRange());
209
                if ($cell->getRow() === (int) $rangeRowsColumns[0][1]) {
210
                    Table\Column::updateStructuredReferences($workSheet, $oldValue, $newValue);
211
                }
212
213
                return;
214
            }
215
        }
216
    }
217
218
    /**
219
     * Set cell value.
220
     *
221
     *    Sets the value for a cell, automatically determining the datatype using the value binder
222
     *
223
     * @param mixed $value Value
224 9523
     *
225
     * @return $this
226
     */
227
    public function setValue($value): self
228 250
    {
229 452
        if (!self::getValueBinder()->bindValue($this, $value)) {
230
            throw new Exception('Value could not be bound to cell.');
231 452
        }
232 249
233 2
        return $this;
234
    }
235 249
236
    /**
237 225
     * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder).
238
     *
239 5117
     * @param mixed $value Value
240
     * @param string $dataType Explicit data type, see DataType::TYPE_*
241 5117
     *        Note that PhpSpreadsheet does not validate that the value and datatype are consistent, in using this
242 224
     *             method, then it is your responsibility as an end-user developer to validate that the value and
243 6459
     *             the datatype match.
244 1
     *       If you do mismatch value and datatype, then the value you enter may be changed to match the datatype
245
     *          that you specify.
246 6458
     *
247
     * @return Cell
248 6458
     */
249 188
    public function setValueExplicit($value, string $dataType = DataType::TYPE_STRING)
250 8256
    {
251
        $oldValue = $this->value;
252 8256
253 16
        // set the value according to data type
254 464
        switch ($dataType) {
255
            case DataType::TYPE_NULL:
256 464
                $this->value = null;
257
258 5
                break;
259 4
            case DataType::TYPE_STRING2:
260
                $dataType = DataType::TYPE_STRING;
261 4
                // no break
262
            case DataType::TYPE_STRING:
263 19
                // Synonym for string
264
            case DataType::TYPE_INLINE:
265 19
                // Rich text
266
                $this->value = DataType::checkString($value);
267
268
                break;
269
            case DataType::TYPE_NUMERIC:
270
                if (is_string($value) && !is_numeric($value)) {
271 9523
                    throw new Exception('Invalid numeric value for datatype Numeric');
272
                }
273 9523
                $this->value = 0 + $value;
274
275
                break;
276
            case DataType::TYPE_FORMULA:
277
                $this->value = (string) $value;
278
279
                break;
280
            case DataType::TYPE_BOOL:
281
                $this->value = (bool) $value;
282
283 45
                break;
284
            case DataType::TYPE_ISO_DATE:
285 45
                $this->value = SharedDate::convertIsoDate($value);
286
                $dataType = DataType::TYPE_NUMERIC;
287
288 45
                break;
289
            case DataType::TYPE_ERROR:
290
                $this->value = DataType::checkErrorCode($value);
291 45
292 23
                break;
293 12
            default:
294 45
                throw new Exception('Invalid datatype: ' . $dataType);
295
        }
296 45
297
        // set the datatype
298 1
        $this->dataType = $dataType;
299
300
        $this->updateInCollection();
301
        $cellCoordinate = $this->getCoordinate();
302
        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

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