diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index ec98ad03..901cb16d 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -42,6 +42,13 @@ if (!defined('PHPEXCEL_ROOT')) { */ class PHPExcel { + /** + * Unique ID + * + * @var string + */ + private $_uniqueID; + /** * Document properties * @@ -63,6 +70,13 @@ class PHPExcel */ private $_workSheetCollection = array(); + /** + * Calculation Engine + * + * @var PHPExcel_Calculation + */ + private $_calculationEngine = NULL; + /** * Active sheet index * @@ -103,6 +117,9 @@ class PHPExcel */ public function __construct() { + $this->_uniqueID = uniqid(); + $this->_calculationEngine = PHPExcel_Calculation::getInstance($this); + // Initialise worksheet collection and add one worksheet $this->_workSheetCollection = array(); $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, * typically so that the PHPExcel object can be unset @@ -141,6 +166,16 @@ class PHPExcel $this->_workSheetCollection = array(); } + /** + * Return the calculation engine for this worksheet + * + * @return PHPExcel_Calculation + */ + public function getCalculationEngine() { + + return $this->_calculationEngine; + } // function getCellCacheController() + /** * Get properties * @@ -824,12 +859,14 @@ class PHPExcel foreach ($sheet->getColumnDimensions() as $columnDimension) { $columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] ); } - } - // also do garbage collection for all the sheets - foreach ($this->getWorksheetIterator() as $sheet) { + // also do garbage collection for all the sheets $sheet->garbageCollect(); } } + public function getID() { + return $this->_uniqueID; + } + } diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 254a4e9c..a2f53721 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -96,13 +96,29 @@ class PHPExcel_Calculation { 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 * * @access private * @var array */ - private static $_calculationCache = array (); + private $_calculationCache = array (); /** @@ -111,7 +127,7 @@ class PHPExcel_Calculation { * @access private * @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; $this->_savedPrecision = ini_get('precision'); if ($this->_savedPrecision < $setPrecision) { ini_set('precision',$setPrecision); } + + if ($workbook !== NULL) { + self::$_workbookSets[$workbook->getID()] = $this; + } + + $this->_workbook = $workbook; } // function __construct() @@ -1702,7 +1724,14 @@ class PHPExcel_Calculation { * @access public * @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)) { self::$_instance = new PHPExcel_Calculation(); } @@ -1710,6 +1739,13 @@ class PHPExcel_Calculation { return self::$_instance; } // 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 @@ -1718,10 +1754,8 @@ class PHPExcel_Calculation { * @access public * @return null */ - public static function flushInstance() { - if (isset(self::$_instance) && (self::$_instance !== NULL)) { - self::$_instance->clearCalculationCache(); - } + public function flushInstance() { + $this->clearCalculationCache(); } // function flushInstance() @@ -1792,7 +1826,7 @@ class PHPExcel_Calculation { * @return boolean */ public function getCalculationCacheEnabled() { - return self::$_calculationCacheEnabled; + return $this->_calculationCacheEnabled; } // function getCalculationCacheEnabled() @@ -1803,7 +1837,7 @@ class PHPExcel_Calculation { * @param boolean $pValue */ public function setCalculationCacheEnabled($pValue = true) { - self::$_calculationCacheEnabled = $pValue; + $this->_calculationCacheEnabled = $pValue; $this->clearCalculationCache(); } // function setCalculationCacheEnabled() @@ -1828,7 +1862,7 @@ class PHPExcel_Calculation { * Clear calculation cache */ public function clearCalculationCache() { - self::$_calculationCache = array(); + $this->_calculationCache = array(); } // function clearCalculationCache() @@ -2206,7 +2240,7 @@ class PHPExcel_Calculation { // Disable calculation cacheing because it only applies to cell calculations, not straight formulae // But don't actually flush any cache $resetCache = $this->getCalculationCacheEnabled(); - self::$_calculationCacheEnabled = false; + $this->_calculationCacheEnabled = FALSE; // Execute the calculation try { $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); @@ -2215,7 +2249,7 @@ class PHPExcel_Calculation { } // Reset calculation cacheing to its previous state - self::$_calculationCacheEnabled = $resetCache; + $this->_calculationCacheEnabled = $resetCache; return $result; } // function calculateFormula() @@ -2250,15 +2284,15 @@ class PHPExcel_Calculation { } // Is calculation cacheing enabled? if ($cellID !== NULL) { - if (self::$_calculationCacheEnabled) { + if ($this->_calculationCacheEnabled) { // Is the value present in calculation cache? $this->_writeDebug('Testing cache value for cell ', $cellID); // echo 'Testing cache value
'; - if (isset(self::$_calculationCache[$wsTitle][$cellID])) { + if (isset($this->_calculationCache[$wsTitle][$cellID])) { // echo 'Value is in cache
'; $this->_writeDebug('Retrieving value for ', $cellID, ' from cache'); // Return the cached result - $returnValue = self::$_calculationCache[$wsTitle][$cellID]; + $returnValue = $this->_calculationCache[$wsTitle][$cellID]; // echo 'Retrieving data value of '.$returnValue.' for '.$cellID.' from cache
'; if (is_array($returnValue)) { $returnValue = PHPExcel_Calculation_Functions::flattenArray($returnValue); @@ -2294,8 +2328,8 @@ class PHPExcel_Calculation { // Save to calculation cache if ($cellID !== NULL) { - if (self::$_calculationCacheEnabled) { - self::$_calculationCache[$wsTitle][$cellID] = $cellValue; + if ($this->_calculationCacheEnabled) { + $this->_calculationCache[$wsTitle][$cellID] = $cellValue; } } diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 2e9cd327..ea37c7ec 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -288,7 +288,7 @@ class PHPExcel_Cell if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { try { // echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value
'; - $result = PHPExcel_Calculation::getInstance()->calculateCellValue($this,$resetLog); + $result = $this->getParent()->getParent()->getCalculationEngine()->calculateCellValue($this,$resetLog); // echo $this->getCoordinate().' calculation result is '.$result.'
'; } catch ( PHPExcel_Exception $ex ) { 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) { - if ($a->_row < $b->_row) { + if ($a->getRow() < $b->getRow()) { return -1; - } elseif ($a->_row > $b->_row) { + } elseif ($a->getRow() > $b->getRow()) { return 1; - } elseif (self::columnIndexFromString($a->_column) < self::columnIndexFromString($b->_column)) { + } elseif (self::columnIndexFromString($a->getColumn()) < self::columnIndexFromString($b->getColumn())) { return -1; } else { return 1;