Minor modifications to cyclic reference count logic in calculation engine
This commit is contained in:
parent
75464688d5
commit
9daca467d6
|
@ -58,8 +58,8 @@ class PHPExcel_CalcEngine_CyclicReferenceStack {
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
*/
|
*/
|
||||||
public function push($value) {
|
public function push($value) {
|
||||||
$this->_stack[] = $value;
|
$this->_stack[$value] = $value;
|
||||||
} // function push()
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pop the last entry from the stack
|
* Pop the last entry from the stack
|
||||||
|
@ -68,7 +68,7 @@ class PHPExcel_CalcEngine_CyclicReferenceStack {
|
||||||
*/
|
*/
|
||||||
public function pop() {
|
public function pop() {
|
||||||
return array_pop($this->_stack);
|
return array_pop($this->_stack);
|
||||||
} // function pop()
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test to see if a specified entry exists on the stack
|
* 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
|
* @param mixed $value The value to test
|
||||||
*/
|
*/
|
||||||
public function onStack($value) {
|
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() {
|
public function clear() {
|
||||||
$this->_stack = array();
|
$this->_stack = array();
|
||||||
} // function push()
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an array of all entries on the stack
|
* Return an array of all entries on the stack
|
||||||
|
@ -95,4 +95,4 @@ class PHPExcel_CalcEngine_CyclicReferenceStack {
|
||||||
return $this->_stack;
|
return $this->_stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // class PHPExcel_CalcEngine_CyclicReferenceStack
|
}
|
||||||
|
|
|
@ -204,7 +204,7 @@ class PHPExcel_Calculation {
|
||||||
* @var integer
|
* @var integer
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private $_cyclicFormulaCount = 0;
|
private $_cyclicFormulaCount = 1;
|
||||||
|
|
||||||
private $_cyclicFormulaCell = '';
|
private $_cyclicFormulaCell = '';
|
||||||
|
|
||||||
|
@ -2236,7 +2236,7 @@ class PHPExcel_Calculation {
|
||||||
$this->formulaError = null;
|
$this->formulaError = null;
|
||||||
$this->_debugLog->clearLog();
|
$this->_debugLog->clearLog();
|
||||||
$this->_cyclicReferenceStack->clear();
|
$this->_cyclicReferenceStack->clear();
|
||||||
$this->_cyclicFormulaCount = 0;
|
$this->_cyclicFormulaCount = 1;
|
||||||
|
|
||||||
self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;
|
self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;
|
||||||
}
|
}
|
||||||
|
@ -2343,24 +2343,22 @@ class PHPExcel_Calculation {
|
||||||
} // function calculateFormula()
|
} // function calculateFormula()
|
||||||
|
|
||||||
|
|
||||||
public function getValueFromCache($worksheetName, $cellID, &$cellValue) {
|
public function getValueFromCache($cellReference, &$cellValue) {
|
||||||
// Is calculation cacheing enabled?
|
// Is calculation cacheing enabled?
|
||||||
// Is the value present in calculation cache?
|
// Is the value present in calculation cache?
|
||||||
//echo 'Test cache for ',$worksheetName,'!',$cellID,PHP_EOL;
|
$this->_debugLog->writeDebugLog('Testing cache value for cell ', $cellReference);
|
||||||
$this->_debugLog->writeDebugLog('Testing cache value for cell ', $worksheetName, '!', $cellID);
|
if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$cellReference]))) {
|
||||||
if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$worksheetName][$cellID]))) {
|
$this->_debugLog->writeDebugLog('Retrieving value for cell ', $cellReference, ' from cache');
|
||||||
//echo 'Retrieve from cache',PHP_EOL;
|
|
||||||
$this->_debugLog->writeDebugLog('Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache');
|
|
||||||
// Return the cached result
|
// Return the cached result
|
||||||
$cellValue = $this->_calculationCache[$worksheetName][$cellID];
|
$cellValue = $this->_calculationCache[$cellReference];
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveValueToCache($worksheetName, $cellID, $cellValue) {
|
public function saveValueToCache($cellReference, $cellValue) {
|
||||||
if ($this->_calculationCacheEnabled) {
|
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;
|
$pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
|
||||||
$wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk";
|
$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;
|
return $cellValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsTitle.'!'.$cellID))) {
|
if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsCellReference))) {
|
||||||
if ($this->cyclicFormulaCount <= 0) {
|
if ($this->cyclicFormulaCount <= 0) {
|
||||||
$this->_cyclicFormulaCell = '';
|
$this->_cyclicFormulaCell = '';
|
||||||
return $this->_raiseFormulaError('Cyclic Reference in Formula');
|
return $this->_raiseFormulaError('Cyclic Reference in Formula');
|
||||||
} elseif (($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) &&
|
} elseif ($this->_cyclicFormulaCell === $wsCellReference) {
|
||||||
($this->_cyclicFormulaCell == $wsTitle.'!'.$cellID)) {
|
|
||||||
$this->_cyclicFormulaCell = '';
|
|
||||||
return $cellValue;
|
|
||||||
} elseif ($this->_cyclicFormulaCell == $wsTitle.'!'.$cellID) {
|
|
||||||
++$this->_cyclicFormulaCount;
|
++$this->_cyclicFormulaCount;
|
||||||
if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) {
|
if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) {
|
||||||
$this->_cyclicFormulaCell = '';
|
$this->_cyclicFormulaCell = '';
|
||||||
|
@ -2408,18 +2403,18 @@ class PHPExcel_Calculation {
|
||||||
if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) {
|
if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) {
|
||||||
return $cellValue;
|
return $cellValue;
|
||||||
}
|
}
|
||||||
$this->_cyclicFormulaCell = $wsTitle.'!'.$cellID;
|
$this->_cyclicFormulaCell = $wsCellReference;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the formula onto the token stack and calculate the value
|
// 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);
|
$cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell);
|
||||||
$this->_cyclicReferenceStack->pop();
|
$this->_cyclicReferenceStack->pop();
|
||||||
|
|
||||||
// Save to calculation cache
|
// Save to calculation cache
|
||||||
if ($cellID !== NULL) {
|
if ($cellID !== NULL) {
|
||||||
$this->saveValueToCache($wsTitle, $cellID, $cellValue);
|
$this->saveValueToCache($wsCellReference, $cellValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the calculated value
|
// Return the calculated value
|
||||||
|
|
Loading…
Reference in New Issue