ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Cells.php
Go to the documentation of this file.
1 <?php
2 
4 
5 use Generator;
11 
12 class 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 }
getCoordinates()
Get a list of all cell coordinates currently held in the collection.
Definition: Cells.php:140
getHighestRow($column=null)
Get highest worksheet row.
Definition: Cells.php:271
getCurrentColumn()
Return the column coordinate of the currently active cell object.
Definition: Cells.php:207
getCoordinate()
Get cell coordinate.
Definition: Cell.php:140
getSortedCoordinates()
Get a sorted list of all cell coordinates currently held in the collection by row and column...
Definition: Cells.php:150
cloneCellCollection(Worksheet $parent)
Clone the cell collection.
Definition: Cells.php:311
getHighestRowAndColumn()
Get highest worksheet column and highest row that have cell records.
Definition: Cells.php:169
add($pCoord, Cell $cell)
Add or update a cell identified by its coordinate into the collection.
Definition: Cells.php:410
$r
Definition: example_031.php:79
__construct(Worksheet $parent, CacheInterface $cache)
Initialise this new cell collection.
Definition: Cells.php:66
getCurrentCoordinate()
Return the cell coordinate of the currently active cell object.
Definition: Cells.php:197
getHighestColumn($row=null)
Get highest worksheet column.
Definition: Cells.php:240
update(Cell $cell)
Add or update a cell in the collection.
Definition: Cells.php:110
getParent()
Return the parent worksheet for this cell collection.
Definition: Cells.php:81
$row
__destruct()
Destroy this cell collection.
Definition: Cells.php:482
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
removeRow($row)
Remove a row, deleting all cells in that row.
Definition: Cells.php:349
getAllCacheKeys()
Returns all known cache keys.
Definition: Cells.php:492
unsetWorksheetCells()
Clear the cell collection and disconnect from our parent.
Definition: Cells.php:462
storeCurrentCell()
Store cell data in cache for the current cell object if it&#39;s "dirty", and the &#39;nullify&#39; the current c...
Definition: Cells.php:384
static columnIndexFromString($pString)
Column index from string.
Definition: Coordinate.php:265
static stringFromColumnIndex($columnIndex)
String from column index.
Definition: Coordinate.php:313
getCurrentRow()
Return the row coordinate of the currently active cell object.
Definition: Cells.php:222
has($pCoord)
Whether the collection holds a cell for the given coordinate.
Definition: Cells.php:93