Cloned worksheet updates were reflected on original (MemoryDrawing)

We need to make note of two things:

- The old code was trying to clone an objectArray, and hence was performing a shallow copy of memoryDrawing objects (the __clone magic function was not getting invoked).
Instead, if one loops over the objectArray, and then clones the individual memory drawing objects, then the __clone function for the MemoryDrawing object is invoked.

- The __clone function for memory drawing was using the clone keyword which does not deal with circular references (Since memoryDrawing object had references to worksheet object, it was encountering an infinite loop). However, serializing and unserializing objects deals with circular references pretty well. 

Fixes #92 
Closes #106
This commit is contained in:
ankitm123 2017-03-06 08:58:19 -05:00 committed by Adrien Crivelli
parent 93e2204774
commit f99eb8dbba
2 changed files with 9 additions and 2 deletions

View File

@ -2,6 +2,8 @@
namespace PhpOffice\PhpSpreadsheet; namespace PhpOffice\PhpSpreadsheet;
use ArrayObject;
/** /**
* Copyright (c) 2006 - 2016 PhpSpreadsheet. * Copyright (c) 2006 - 2016 PhpSpreadsheet.
* *
@ -2975,7 +2977,12 @@ class Worksheet implements IComparable
$newCollection->copyCellCollection($this); $newCollection->copyCellCollection($this);
$this->cellCollection = $newCollection; $this->cellCollection = $newCollection;
} elseif ($key == 'drawingCollection') { } elseif ($key == 'drawingCollection') {
$newCollection = clone $this->drawingCollection; $newCollection = new ArrayObject();
foreach ($this->drawingCollection as $id => $item) {
if (is_object($item)) {
$newCollection[$id] = clone $this->drawingCollection[$id];
}
}
$this->drawingCollection = $newCollection; $this->drawingCollection = $newCollection;
} elseif (($key == 'autoFilter') && ($this->autoFilter instanceof Worksheet\AutoFilter)) { } elseif (($key == 'autoFilter') && ($this->autoFilter instanceof Worksheet\AutoFilter)) {
$newAutoFilter = clone $this->autoFilter; $newAutoFilter = clone $this->autoFilter;

View File

@ -197,7 +197,7 @@ class MemoryDrawing extends BaseDrawing implements \PhpOffice\PhpSpreadsheet\ICo
$vars = get_object_vars($this); $vars = get_object_vars($this);
foreach ($vars as $key => $value) { foreach ($vars as $key => $value) {
if (is_object($value)) { if (is_object($value)) {
$this->$key = clone $value; $this->$key = unserialize(serialize($value));
} else { } else {
$this->$key = $value; $this->$key = $value;
} }