From 9daca467d61fc37130b6fe8485a12396e99b6c8a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 5 Dec 2014 23:59:41 +0000 Subject: [PATCH] Minor modifications to cyclic reference count logic in calculation engine --- .../CalcEngine/CyclicReferenceStack.php | 12 +++--- Classes/PHPExcel/Calculation.php | 39 ++++++++----------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php index a633c2c3..5cd0b909 100644 --- a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php +++ b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php @@ -58,8 +58,8 @@ class PHPExcel_CalcEngine_CyclicReferenceStack { * @param mixed $value */ public function push($value) { - $this->_stack[] = $value; - } // function push() + $this->_stack[$value] = $value; + } /** * Pop the last entry from the stack @@ -68,7 +68,7 @@ class PHPExcel_CalcEngine_CyclicReferenceStack { */ public function pop() { return array_pop($this->_stack); - } // function pop() + } /** * Test to see if a specified entry exists on the stack @@ -76,7 +76,7 @@ class PHPExcel_CalcEngine_CyclicReferenceStack { * @param mixed $value The value to test */ public function onStack($value) { - return in_array($value, $this->_stack); + return isset($this->_stack[$value]); } /** @@ -84,7 +84,7 @@ class PHPExcel_CalcEngine_CyclicReferenceStack { */ public function clear() { $this->_stack = array(); - } // function push() + } /** * Return an array of all entries on the stack @@ -95,4 +95,4 @@ class PHPExcel_CalcEngine_CyclicReferenceStack { return $this->_stack; } -} // class PHPExcel_CalcEngine_CyclicReferenceStack +} diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 9a0bf0f0..1f8c9323 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -204,7 +204,7 @@ class PHPExcel_Calculation { * @var integer * */ - private $_cyclicFormulaCount = 0; + private $_cyclicFormulaCount = 1; private $_cyclicFormulaCell = ''; @@ -2236,7 +2236,7 @@ class PHPExcel_Calculation { $this->formulaError = null; $this->_debugLog->clearLog(); $this->_cyclicReferenceStack->clear(); - $this->_cyclicFormulaCount = 0; + $this->_cyclicFormulaCount = 1; self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; } @@ -2343,24 +2343,22 @@ class PHPExcel_Calculation { } // function calculateFormula() - public function getValueFromCache($worksheetName, $cellID, &$cellValue) { + public function getValueFromCache($cellReference, &$cellValue) { // Is calculation cacheing enabled? // Is the value present in calculation cache? -//echo 'Test cache for ',$worksheetName,'!',$cellID,PHP_EOL; - $this->_debugLog->writeDebugLog('Testing cache value for cell ', $worksheetName, '!', $cellID); - if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$worksheetName][$cellID]))) { -//echo 'Retrieve from cache',PHP_EOL; - $this->_debugLog->writeDebugLog('Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache'); + $this->_debugLog->writeDebugLog('Testing cache value for cell ', $cellReference); + if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$cellReference]))) { + $this->_debugLog->writeDebugLog('Retrieving value for cell ', $cellReference, ' from cache'); // Return the cached result - $cellValue = $this->_calculationCache[$worksheetName][$cellID]; + $cellValue = $this->_calculationCache[$cellReference]; return TRUE; } return FALSE; } - public function saveValueToCache($worksheetName, $cellID, $cellValue) { + public function saveValueToCache($cellReference, $cellValue) { if ($this->_calculationCacheEnabled) { - $this->_calculationCache[$worksheetName][$cellID] = $cellValue; + $this->_calculationCache[$cellReference] = $cellValue; } } @@ -2385,20 +2383,17 @@ class PHPExcel_Calculation { $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; + $wsCellReference = $wsTitle . '!' . $cellID; - if (($cellID !== NULL) && ($this->getValueFromCache($wsTitle, $cellID, $cellValue))) { + if (($cellID !== NULL) && ($this->getValueFromCache($wsCellReference, $cellValue))) { return $cellValue; } - if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsTitle.'!'.$cellID))) { - if ($this->cyclicFormulaCount <= 0) { + if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsCellReference))) { + if ($this->cyclicFormulaCount <= 0) { $this->_cyclicFormulaCell = ''; return $this->_raiseFormulaError('Cyclic Reference in Formula'); - } elseif (($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) && - ($this->_cyclicFormulaCell == $wsTitle.'!'.$cellID)) { - $this->_cyclicFormulaCell = ''; - return $cellValue; - } elseif ($this->_cyclicFormulaCell == $wsTitle.'!'.$cellID) { + } elseif ($this->_cyclicFormulaCell === $wsCellReference) { ++$this->_cyclicFormulaCount; if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { $this->_cyclicFormulaCell = ''; @@ -2408,18 +2403,18 @@ class PHPExcel_Calculation { if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { return $cellValue; } - $this->_cyclicFormulaCell = $wsTitle.'!'.$cellID; + $this->_cyclicFormulaCell = $wsCellReference; } } // Parse the formula onto the token stack and calculate the value - $this->_cyclicReferenceStack->push($wsTitle.'!'.$cellID); + $this->_cyclicReferenceStack->push($wsCellReference); $cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell); $this->_cyclicReferenceStack->pop(); // Save to calculation cache if ($cellID !== NULL) { - $this->saveValueToCache($wsTitle, $cellID, $cellValue); + $this->saveValueToCache($wsCellReference, $cellValue); } // Return the calculated value