ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Cells.php
Go to the documentation of this file.
1<?php
2
4
5use Generator;
8use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
11
12class Cells
13{
17 private $cache;
18
24 private $parent;
25
31 private $currentCell;
32
39
45 private $currentCellIsDirty = false;
46
52 private $index = [];
53
59 private $cachePrefix;
60
67 {
68 // Set our parent worksheet.
69 // This is maintained here to facilitate re-attaching it to Cell objects when
70 // they are woken from a serialized state
71 $this->parent = $parent;
72 $this->cache = $cache;
73 $this->cachePrefix = $this->getUniqueID();
74 }
75
81 public function getParent()
82 {
83 return $this->parent;
84 }
85
93 public function has($pCoord)
94 {
95 if ($pCoord === $this->currentCoordinate) {
96 return true;
97 }
98
99 // Check if the requested entry exists in the index
100 return isset($this->index[$pCoord]);
101 }
102
110 public function update(Cell $cell)
111 {
112 return $this->add($cell->getCoordinate(), $cell);
113 }
114
120 public function delete($pCoord): void
121 {
122 if ($pCoord === $this->currentCoordinate && $this->currentCell !== null) {
123 $this->currentCell->detach();
124 $this->currentCoordinate = null;
125 $this->currentCell = null;
126 $this->currentCellIsDirty = false;
127 }
128
129 unset($this->index[$pCoord]);
130
131 // Delete the entry from cache
132 $this->cache->delete($this->cachePrefix . $pCoord);
133 }
134
140 public function getCoordinates()
141 {
142 return array_keys($this->index);
143 }
144
150 public function getSortedCoordinates()
151 {
152 $sortKeys = [];
153 foreach ($this->getCoordinates() as $coord) {
154 $column = '';
155 $row = 0;
156 sscanf($coord, '%[A-Z]%d', $column, $row);
157 $sortKeys[sprintf('%09d%3s', $row, $column)] = $coord;
158 }
159 ksort($sortKeys);
160
161 return array_values($sortKeys);
162 }
163
169 public function getHighestRowAndColumn()
170 {
171 // Lookup highest column and highest row
172 $col = ['A' => '1A'];
173 $row = [1];
174 foreach ($this->getCoordinates() as $coord) {
175 $c = '';
176 $r = 0;
177 sscanf($coord, '%[A-Z]%d', $c, $r);
178 $row[$r] = $r;
179 $col[$c] = strlen($c) . $c;
180 }
181
182 // Determine highest column and row
183 $highestRow = max($row);
184 $highestColumn = substr(max($col), 1);
185
186 return [
187 'row' => $highestRow,
188 'column' => $highestColumn,
189 ];
190 }
191
197 public function getCurrentCoordinate()
198 {
200 }
201
207 public function getCurrentColumn()
208 {
209 $column = '';
210 $row = 0;
211
212 sscanf($this->currentCoordinate, '%[A-Z]%d', $column, $row);
213
214 return $column;
215 }
216
222 public function getCurrentRow()
223 {
224 $column = '';
225 $row = 0;
226
227 sscanf($this->currentCoordinate, '%[A-Z]%d', $column, $row);
228
229 return (int) $row;
230 }
231
240 public function getHighestColumn($row = null)
241 {
242 if ($row === null) {
243 $colRow = $this->getHighestRowAndColumn();
244
245 return $colRow['column'];
246 }
247
248 $columnList = [1];
249 foreach ($this->getCoordinates() as $coord) {
250 $c = '';
251 $r = 0;
252
253 sscanf($coord, '%[A-Z]%d', $c, $r);
254 if ($r != $row) {
255 continue;
256 }
257 $columnList[] = Coordinate::columnIndexFromString($c);
258 }
259
260 return Coordinate::stringFromColumnIndex(max($columnList));
261 }
262
271 public function getHighestRow($column = null)
272 {
273 if ($column === null) {
274 $colRow = $this->getHighestRowAndColumn();
275
276 return $colRow['row'];
277 }
278
279 $rowList = [0];
280 foreach ($this->getCoordinates() as $coord) {
281 $c = '';
282 $r = 0;
283
284 sscanf($coord, '%[A-Z]%d', $c, $r);
285 if ($c != $column) {
286 continue;
287 }
288 $rowList[] = $r;
289 }
290
291 return max($rowList);
292 }
293
299 private function getUniqueID()
300 {
301 return uniqid('phpspreadsheet.', true) . '.';
302 }
303
312 {
313 $this->storeCurrentCell();
314 $newCollection = clone $this;
315
316 $newCollection->parent = $parent;
317 if (($newCollection->currentCell !== null) && (is_object($newCollection->currentCell))) {
318 $newCollection->currentCell->attach($this);
319 }
320
321 // Get old values
322 $oldKeys = $newCollection->getAllCacheKeys();
323 $oldValues = $newCollection->cache->getMultiple($oldKeys);
324 $newValues = [];
325 $oldCachePrefix = $newCollection->cachePrefix;
326
327 // Change prefix
328 $newCollection->cachePrefix = $newCollection->getUniqueID();
329 foreach ($oldValues as $oldKey => $value) {
330 $newValues[str_replace($oldCachePrefix, $newCollection->cachePrefix, $oldKey)] = clone $value;
331 }
332
333 // Store new values
334 $stored = $newCollection->cache->setMultiple($newValues);
335 if (!$stored) {
336 $newCollection->__destruct();
337
338 throw new PhpSpreadsheetException('Failed to copy cells in cache');
339 }
340
341 return $newCollection;
342 }
343
349 public function removeRow($row): void
350 {
351 foreach ($this->getCoordinates() as $coord) {
352 $c = '';
353 $r = 0;
354
355 sscanf($coord, '%[A-Z]%d', $c, $r);
356 if ($r == $row) {
357 $this->delete($coord);
358 }
359 }
360 }
361
367 public function removeColumn($column): void
368 {
369 foreach ($this->getCoordinates() as $coord) {
370 $c = '';
371 $r = 0;
372
373 sscanf($coord, '%[A-Z]%d', $c, $r);
374 if ($c == $column) {
375 $this->delete($coord);
376 }
377 }
378 }
379
384 private function storeCurrentCell(): void
385 {
386 if ($this->currentCellIsDirty && !empty($this->currentCoordinate)) {
387 $this->currentCell->detach();
388
389 $stored = $this->cache->set($this->cachePrefix . $this->currentCoordinate, $this->currentCell);
390 if (!$stored) {
391 $this->__destruct();
392
393 throw new PhpSpreadsheetException("Failed to store cell {$this->currentCoordinate} in cache");
394 }
395 $this->currentCellIsDirty = false;
396 }
397
398 $this->currentCoordinate = null;
399 $this->currentCell = null;
400 }
401
410 public function add($pCoord, Cell $cell)
411 {
412 if ($pCoord !== $this->currentCoordinate) {
413 $this->storeCurrentCell();
414 }
415 $this->index[$pCoord] = true;
416
417 $this->currentCoordinate = $pCoord;
418 $this->currentCell = $cell;
419 $this->currentCellIsDirty = true;
420
421 return $cell;
422 }
423
431 public function get($pCoord)
432 {
433 if ($pCoord === $this->currentCoordinate) {
434 return $this->currentCell;
435 }
436 $this->storeCurrentCell();
437
438 // Return null if requested entry doesn't exist in collection
439 if (!$this->has($pCoord)) {
440 return null;
441 }
442
443 // Check if the entry that has been requested actually exists
444 $cell = $this->cache->get($this->cachePrefix . $pCoord);
445 if ($cell === null) {
446 throw new PhpSpreadsheetException("Cell entry {$pCoord} no longer exists in cache. This probably means that the cache was cleared by someone else.");
447 }
448
449 // Set current entry to the requested entry
450 $this->currentCoordinate = $pCoord;
451 $this->currentCell = $cell;
452 // Re-attach this as the cell's parent
453 $this->currentCell->attach($this);
454
455 // Return requested entry
456 return $this->currentCell;
457 }
458
462 public function unsetWorksheetCells(): void
463 {
464 if ($this->currentCell !== null) {
465 $this->currentCell->detach();
466 $this->currentCell = null;
467 $this->currentCoordinate = null;
468 }
469
470 // Flush the cache
471 $this->__destruct();
472
473 $this->index = [];
474
475 // detach ourself from the worksheet, so that it can then delete this object successfully
476 $this->parent = null;
477 }
478
482 public function __destruct()
483 {
484 $this->cache->deleteMultiple($this->getAllCacheKeys());
485 }
486
492 private function getAllCacheKeys()
493 {
494 foreach ($this->getCoordinates() as $coordinate) {
495 yield $this->cachePrefix . $coordinate;
496 }
497 }
498}
An exception for terminatinating execution or to throw for unit testing.
getCoordinate()
Get cell coordinate.
Definition: Cell.php:140
Helper class to manipulate cell coordinates.
Definition: Coordinate.php:15
static columnIndexFromString($pString)
Column index from string.
Definition: Coordinate.php:265
static stringFromColumnIndex($columnIndex)
String from column index.
Definition: Coordinate.php:313
add($pCoord, Cell $cell)
Add or update a cell identified by its coordinate into the collection.
Definition: Cells.php:410
getCoordinates()
Get a list of all cell coordinates currently held in the collection.
Definition: Cells.php:140
getHighestRowAndColumn()
Get highest worksheet column and highest row that have cell records.
Definition: Cells.php:169
has($pCoord)
Whether the collection holds a cell for the given coordinate.
Definition: Cells.php:93
update(Cell $cell)
Add or update a cell in the collection.
Definition: Cells.php:110
unsetWorksheetCells()
Clear the cell collection and disconnect from our parent.
Definition: Cells.php:462
cloneCellCollection(Worksheet $parent)
Clone the cell collection.
Definition: Cells.php:311
getHighestColumn($row=null)
Get highest worksheet column.
Definition: Cells.php:240
getHighestRow($column=null)
Get highest worksheet row.
Definition: Cells.php:271
storeCurrentCell()
Store cell data in cache for the current cell object if it's "dirty", and the 'nullify' the current c...
Definition: Cells.php:384
getAllCacheKeys()
Returns all known cache keys.
Definition: Cells.php:492
removeRow($row)
Remove a row, deleting all cells in that row.
Definition: Cells.php:349
getSortedCoordinates()
Get a sorted list of all cell coordinates currently held in the collection by row and column.
Definition: Cells.php:150
removeColumn($column)
Remove a column, deleting all cells in that column.
Definition: Cells.php:367
getUniqueID()
Generate a unique ID for cache referencing.
Definition: Cells.php:299
getParent()
Return the parent worksheet for this cell collection.
Definition: Cells.php:81
getCurrentRow()
Return the row coordinate of the currently active cell object.
Definition: Cells.php:222
__construct(Worksheet $parent, CacheInterface $cache)
Initialise this new cell collection.
Definition: Cells.php:66
__destruct()
Destroy this cell collection.
Definition: Cells.php:482
getCurrentCoordinate()
Return the cell coordinate of the currently active cell object.
Definition: Cells.php:197
getCurrentColumn()
Return the column coordinate of the currently active cell object.
Definition: Cells.php:207
$r
Definition: example_031.php:79
$row