Convert singleton calculation engine to multiton
This commit is contained in:
parent
242f69bb29
commit
1e1a6ac361
|
@ -42,6 +42,13 @@ if (!defined('PHPEXCEL_ROOT')) {
|
||||||
*/
|
*/
|
||||||
class PHPExcel
|
class PHPExcel
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Unique ID
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $_uniqueID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Document properties
|
* Document properties
|
||||||
*
|
*
|
||||||
|
@ -63,6 +70,13 @@ class PHPExcel
|
||||||
*/
|
*/
|
||||||
private $_workSheetCollection = array();
|
private $_workSheetCollection = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculation Engine
|
||||||
|
*
|
||||||
|
* @var PHPExcel_Calculation
|
||||||
|
*/
|
||||||
|
private $_calculationEngine = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Active sheet index
|
* Active sheet index
|
||||||
*
|
*
|
||||||
|
@ -103,6 +117,9 @@ class PHPExcel
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
$this->_uniqueID = uniqid();
|
||||||
|
$this->_calculationEngine = PHPExcel_Calculation::getInstance($this);
|
||||||
|
|
||||||
// Initialise worksheet collection and add one worksheet
|
// Initialise worksheet collection and add one worksheet
|
||||||
$this->_workSheetCollection = array();
|
$this->_workSheetCollection = array();
|
||||||
$this->_workSheetCollection[] = new PHPExcel_Worksheet($this);
|
$this->_workSheetCollection[] = new PHPExcel_Worksheet($this);
|
||||||
|
@ -127,6 +144,14 @@ class PHPExcel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy this workbook
|
||||||
|
*/
|
||||||
|
public function __destruct() {
|
||||||
|
PHPExcel_Calculation::unsetInstance($this);
|
||||||
|
$this->disconnectWorksheets();
|
||||||
|
} // function __destruct()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect all worksheets from this PHPExcel workbook object,
|
* Disconnect all worksheets from this PHPExcel workbook object,
|
||||||
* typically so that the PHPExcel object can be unset
|
* typically so that the PHPExcel object can be unset
|
||||||
|
@ -141,6 +166,16 @@ class PHPExcel
|
||||||
$this->_workSheetCollection = array();
|
$this->_workSheetCollection = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the calculation engine for this worksheet
|
||||||
|
*
|
||||||
|
* @return PHPExcel_Calculation
|
||||||
|
*/
|
||||||
|
public function getCalculationEngine() {
|
||||||
|
|
||||||
|
return $this->_calculationEngine;
|
||||||
|
} // function getCellCacheController()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get properties
|
* Get properties
|
||||||
*
|
*
|
||||||
|
@ -824,12 +859,14 @@ class PHPExcel
|
||||||
foreach ($sheet->getColumnDimensions() as $columnDimension) {
|
foreach ($sheet->getColumnDimensions() as $columnDimension) {
|
||||||
$columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] );
|
$columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// also do garbage collection for all the sheets
|
// also do garbage collection for all the sheets
|
||||||
foreach ($this->getWorksheetIterator() as $sheet) {
|
|
||||||
$sheet->garbageCollect();
|
$sheet->garbageCollect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getID() {
|
||||||
|
return $this->_uniqueID;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,13 +96,29 @@ class PHPExcel_Calculation {
|
||||||
private static $_instance;
|
private static $_instance;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of the workbook this Calculation Engine is using
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var PHPExcel
|
||||||
|
*/
|
||||||
|
private $_workbook;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of instances of the calculation engine that we've instantiated
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var PHPExcel_Calculation[]
|
||||||
|
*/
|
||||||
|
private static $_workbookSets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculation cache
|
* Calculation cache
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $_calculationCache = array ();
|
private $_calculationCache = array ();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,7 +127,7 @@ class PHPExcel_Calculation {
|
||||||
* @access private
|
* @access private
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
private static $_calculationCacheEnabled = true;
|
private $_calculationCacheEnabled = true;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1671,12 +1687,18 @@ class PHPExcel_Calculation {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private function __construct() {
|
private function __construct(PHPExcel $workbook = NULL) {
|
||||||
$setPrecision = (PHP_INT_SIZE == 4) ? 12 : 16;
|
$setPrecision = (PHP_INT_SIZE == 4) ? 12 : 16;
|
||||||
$this->_savedPrecision = ini_get('precision');
|
$this->_savedPrecision = ini_get('precision');
|
||||||
if ($this->_savedPrecision < $setPrecision) {
|
if ($this->_savedPrecision < $setPrecision) {
|
||||||
ini_set('precision',$setPrecision);
|
ini_set('precision',$setPrecision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($workbook !== NULL) {
|
||||||
|
self::$_workbookSets[$workbook->getID()] = $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_workbook = $workbook;
|
||||||
} // function __construct()
|
} // function __construct()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1702,7 +1724,14 @@ class PHPExcel_Calculation {
|
||||||
* @access public
|
* @access public
|
||||||
* @return PHPExcel_Calculation
|
* @return PHPExcel_Calculation
|
||||||
*/
|
*/
|
||||||
public static function getInstance() {
|
public static function getInstance(PHPExcel $workbook = NULL) {
|
||||||
|
if ($workbook !== NULL) {
|
||||||
|
if (isset(self::$_workbookSets[$workbook->getID()])) {
|
||||||
|
return self::$_workbookSets[$workbook->getID()];
|
||||||
|
}
|
||||||
|
return new PHPExcel_Calculation($workbook);
|
||||||
|
}
|
||||||
|
|
||||||
if (!isset(self::$_instance) || (self::$_instance === NULL)) {
|
if (!isset(self::$_instance) || (self::$_instance === NULL)) {
|
||||||
self::$_instance = new PHPExcel_Calculation();
|
self::$_instance = new PHPExcel_Calculation();
|
||||||
}
|
}
|
||||||
|
@ -1710,6 +1739,13 @@ class PHPExcel_Calculation {
|
||||||
return self::$_instance;
|
return self::$_instance;
|
||||||
} // function getInstance()
|
} // function getInstance()
|
||||||
|
|
||||||
|
public static function unsetInstance(PHPExcel $workbook = NULL) {
|
||||||
|
if ($workbook !== NULL) {
|
||||||
|
if (isset(self::$_workbookSets[$workbook->getID()])) {
|
||||||
|
unset(self::$_workbookSets[$workbook->getID()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush the calculation cache for any existing instance of this class
|
* Flush the calculation cache for any existing instance of this class
|
||||||
|
@ -1718,10 +1754,8 @@ class PHPExcel_Calculation {
|
||||||
* @access public
|
* @access public
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
public static function flushInstance() {
|
public function flushInstance() {
|
||||||
if (isset(self::$_instance) && (self::$_instance !== NULL)) {
|
$this->clearCalculationCache();
|
||||||
self::$_instance->clearCalculationCache();
|
|
||||||
}
|
|
||||||
} // function flushInstance()
|
} // function flushInstance()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1792,7 +1826,7 @@ class PHPExcel_Calculation {
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function getCalculationCacheEnabled() {
|
public function getCalculationCacheEnabled() {
|
||||||
return self::$_calculationCacheEnabled;
|
return $this->_calculationCacheEnabled;
|
||||||
} // function getCalculationCacheEnabled()
|
} // function getCalculationCacheEnabled()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1803,7 +1837,7 @@ class PHPExcel_Calculation {
|
||||||
* @param boolean $pValue
|
* @param boolean $pValue
|
||||||
*/
|
*/
|
||||||
public function setCalculationCacheEnabled($pValue = true) {
|
public function setCalculationCacheEnabled($pValue = true) {
|
||||||
self::$_calculationCacheEnabled = $pValue;
|
$this->_calculationCacheEnabled = $pValue;
|
||||||
$this->clearCalculationCache();
|
$this->clearCalculationCache();
|
||||||
} // function setCalculationCacheEnabled()
|
} // function setCalculationCacheEnabled()
|
||||||
|
|
||||||
|
@ -1828,7 +1862,7 @@ class PHPExcel_Calculation {
|
||||||
* Clear calculation cache
|
* Clear calculation cache
|
||||||
*/
|
*/
|
||||||
public function clearCalculationCache() {
|
public function clearCalculationCache() {
|
||||||
self::$_calculationCache = array();
|
$this->_calculationCache = array();
|
||||||
} // function clearCalculationCache()
|
} // function clearCalculationCache()
|
||||||
|
|
||||||
|
|
||||||
|
@ -2206,7 +2240,7 @@ class PHPExcel_Calculation {
|
||||||
// Disable calculation cacheing because it only applies to cell calculations, not straight formulae
|
// Disable calculation cacheing because it only applies to cell calculations, not straight formulae
|
||||||
// But don't actually flush any cache
|
// But don't actually flush any cache
|
||||||
$resetCache = $this->getCalculationCacheEnabled();
|
$resetCache = $this->getCalculationCacheEnabled();
|
||||||
self::$_calculationCacheEnabled = false;
|
$this->_calculationCacheEnabled = FALSE;
|
||||||
// Execute the calculation
|
// Execute the calculation
|
||||||
try {
|
try {
|
||||||
$result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell));
|
$result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell));
|
||||||
|
@ -2215,7 +2249,7 @@ class PHPExcel_Calculation {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset calculation cacheing to its previous state
|
// Reset calculation cacheing to its previous state
|
||||||
self::$_calculationCacheEnabled = $resetCache;
|
$this->_calculationCacheEnabled = $resetCache;
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
} // function calculateFormula()
|
} // function calculateFormula()
|
||||||
|
@ -2250,15 +2284,15 @@ class PHPExcel_Calculation {
|
||||||
}
|
}
|
||||||
// Is calculation cacheing enabled?
|
// Is calculation cacheing enabled?
|
||||||
if ($cellID !== NULL) {
|
if ($cellID !== NULL) {
|
||||||
if (self::$_calculationCacheEnabled) {
|
if ($this->_calculationCacheEnabled) {
|
||||||
// Is the value present in calculation cache?
|
// Is the value present in calculation cache?
|
||||||
$this->_writeDebug('Testing cache value for cell ', $cellID);
|
$this->_writeDebug('Testing cache value for cell ', $cellID);
|
||||||
// echo 'Testing cache value<br />';
|
// echo 'Testing cache value<br />';
|
||||||
if (isset(self::$_calculationCache[$wsTitle][$cellID])) {
|
if (isset($this->_calculationCache[$wsTitle][$cellID])) {
|
||||||
// echo 'Value is in cache<br />';
|
// echo 'Value is in cache<br />';
|
||||||
$this->_writeDebug('Retrieving value for ', $cellID, ' from cache');
|
$this->_writeDebug('Retrieving value for ', $cellID, ' from cache');
|
||||||
// Return the cached result
|
// Return the cached result
|
||||||
$returnValue = self::$_calculationCache[$wsTitle][$cellID];
|
$returnValue = $this->_calculationCache[$wsTitle][$cellID];
|
||||||
// echo 'Retrieving data value of '.$returnValue.' for '.$cellID.' from cache<br />';
|
// echo 'Retrieving data value of '.$returnValue.' for '.$cellID.' from cache<br />';
|
||||||
if (is_array($returnValue)) {
|
if (is_array($returnValue)) {
|
||||||
$returnValue = PHPExcel_Calculation_Functions::flattenArray($returnValue);
|
$returnValue = PHPExcel_Calculation_Functions::flattenArray($returnValue);
|
||||||
|
@ -2294,8 +2328,8 @@ class PHPExcel_Calculation {
|
||||||
|
|
||||||
// Save to calculation cache
|
// Save to calculation cache
|
||||||
if ($cellID !== NULL) {
|
if ($cellID !== NULL) {
|
||||||
if (self::$_calculationCacheEnabled) {
|
if ($this->_calculationCacheEnabled) {
|
||||||
self::$_calculationCache[$wsTitle][$cellID] = $cellValue;
|
$this->_calculationCache[$wsTitle][$cellID] = $cellValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,7 @@ class PHPExcel_Cell
|
||||||
if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) {
|
if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) {
|
||||||
try {
|
try {
|
||||||
// echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value<br />';
|
// echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value<br />';
|
||||||
$result = PHPExcel_Calculation::getInstance()->calculateCellValue($this,$resetLog);
|
$result = $this->getParent()->getParent()->getCalculationEngine()->calculateCellValue($this,$resetLog);
|
||||||
// echo $this->getCoordinate().' calculation result is '.$result.'<br />';
|
// echo $this->getCoordinate().' calculation result is '.$result.'<br />';
|
||||||
} catch ( PHPExcel_Exception $ex ) {
|
} catch ( PHPExcel_Exception $ex ) {
|
||||||
if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) {
|
if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) {
|
||||||
|
@ -859,11 +859,11 @@ class PHPExcel_Cell
|
||||||
*/
|
*/
|
||||||
public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b)
|
public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b)
|
||||||
{
|
{
|
||||||
if ($a->_row < $b->_row) {
|
if ($a->getRow() < $b->getRow()) {
|
||||||
return -1;
|
return -1;
|
||||||
} elseif ($a->_row > $b->_row) {
|
} elseif ($a->getRow() > $b->getRow()) {
|
||||||
return 1;
|
return 1;
|
||||||
} elseif (self::columnIndexFromString($a->_column) < self::columnIndexFromString($b->_column)) {
|
} elseif (self::columnIndexFromString($a->getColumn()) < self::columnIndexFromString($b->getColumn())) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in New Issue