Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Cell;
4
 
5
use PhpOffice\PhpSpreadsheet\Exception;
6
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
7
use Stringable;
8
 
9
/**
10
 * @implements AddressRange<CellAddress>
11
 */
12
class CellRange implements AddressRange, Stringable
13
{
14
    protected CellAddress $from;
15
 
16
    protected CellAddress $to;
17
 
18
    public function __construct(CellAddress $from, CellAddress $to)
19
    {
20
        $this->validateFromTo($from, $to);
21
    }
22
 
23
    private function validateFromTo(CellAddress $from, CellAddress $to): void
24
    {
25
        // Identify actual top-left and bottom-right values (in case we've been given top-right and bottom-left)
26
        $firstColumn = min($from->columnId(), $to->columnId());
27
        $firstRow = min($from->rowId(), $to->rowId());
28
        $lastColumn = max($from->columnId(), $to->columnId());
29
        $lastRow = max($from->rowId(), $to->rowId());
30
 
31
        $fromWorksheet = $from->worksheet();
32
        $toWorksheet = $to->worksheet();
33
        $this->validateWorksheets($fromWorksheet, $toWorksheet);
34
 
35
        $this->from = $this->cellAddressWrapper($firstColumn, $firstRow, $fromWorksheet);
36
        $this->to = $this->cellAddressWrapper($lastColumn, $lastRow, $toWorksheet);
37
    }
38
 
39
    private function validateWorksheets(?Worksheet $fromWorksheet, ?Worksheet $toWorksheet): void
40
    {
41
        if ($fromWorksheet !== null && $toWorksheet !== null) {
42
            // We could simply compare worksheets rather than worksheet titles; but at some point we may introduce
43
            //    support for 3d ranges; and at that point we drop this check and let the validation fall through
44
            //    to the check for same workbook; but unless we check on titles, this test will also detect if the
45
            //    worksheets are in different spreadsheets, and the next check will never execute or throw its
46
            //    own exception.
47
            if ($fromWorksheet->getTitle() !== $toWorksheet->getTitle()) {
48
                throw new Exception('3d Cell Ranges are not supported');
49
            } elseif ($fromWorksheet->getParent() !== $toWorksheet->getParent()) {
50
                throw new Exception('Worksheets must be in the same spreadsheet');
51
            }
52
        }
53
    }
54
 
55
    private function cellAddressWrapper(int $column, int $row, ?Worksheet $worksheet = null): CellAddress
56
    {
57
        $cellAddress = Coordinate::stringFromColumnIndex($column) . (string) $row;
58
 
59
        return new class ($cellAddress, $worksheet) extends CellAddress {
60
            public function nextRow(int $offset = 1): CellAddress
61
            {
62
                /** @var CellAddress $result */
63
                $result = parent::nextRow($offset);
64
                $this->rowId = $result->rowId;
65
                $this->cellAddress = $result->cellAddress;
66
 
67
                return $this;
68
            }
69
 
70
            public function previousRow(int $offset = 1): CellAddress
71
            {
72
                /** @var CellAddress $result */
73
                $result = parent::previousRow($offset);
74
                $this->rowId = $result->rowId;
75
                $this->cellAddress = $result->cellAddress;
76
 
77
                return $this;
78
            }
79
 
80
            public function nextColumn(int $offset = 1): CellAddress
81
            {
82
                /** @var CellAddress $result */
83
                $result = parent::nextColumn($offset);
84
                $this->columnId = $result->columnId;
85
                $this->columnName = $result->columnName;
86
                $this->cellAddress = $result->cellAddress;
87
 
88
                return $this;
89
            }
90
 
91
            public function previousColumn(int $offset = 1): CellAddress
92
            {
93
                /** @var CellAddress $result */
94
                $result = parent::previousColumn($offset);
95
                $this->columnId = $result->columnId;
96
                $this->columnName = $result->columnName;
97
                $this->cellAddress = $result->cellAddress;
98
 
99
                return $this;
100
            }
101
        };
102
    }
103
 
104
    public function from(): CellAddress
105
    {
106
        // Re-order from/to in case the cell addresses have been modified
107
        $this->validateFromTo($this->from, $this->to);
108
 
109
        return $this->from;
110
    }
111
 
112
    public function to(): CellAddress
113
    {
114
        // Re-order from/to in case the cell addresses have been modified
115
        $this->validateFromTo($this->from, $this->to);
116
 
117
        return $this->to;
118
    }
119
 
120
    public function __toString(): string
121
    {
122
        // Re-order from/to in case the cell addresses have been modified
123
        $this->validateFromTo($this->from, $this->to);
124
 
125
        if ($this->from->cellAddress() === $this->to->cellAddress()) {
126
            return "{$this->from->fullCellAddress()}";
127
        }
128
 
129
        $fromAddress = $this->from->fullCellAddress();
130
        $toAddress = $this->to->cellAddress();
131
 
132
        return "{$fromAddress}:{$toAddress}";
133
    }
134
}